我如何在 laravel 中搜索多个关键字。?
how can i search multiple keywords in laravel .?
这是我的控制器
$term = $request->get('q');
// return $request->q;
$products = Post::whereHas('user', function($query) use($term) {
$query->where('name', 'like', '%'.$term.'%');
})->orWhere('tags','LIKE','%'.$term.'%')->get();
return view('pages.search', compact('products','users'));
这对单个关键字搜索很有用。但我想将它用于多个关键字。像 laravel php 等。当我搜索多个值时请指导我,如 abc php laravel 或任何它应该工作的东西。如果标签存在于不同的列中,例如 php 出现在第一列中,而 laravel 出现在下一列中,当我搜索 php laravel 时,它应该向我显示两个列值。
可能有更好的方法来做到这一点,比如使用 CloudSearch/Algolia,但这是一个对我们有用的解决方案:
// Split the terms by word.
$terms = explode(" ", request('q'));
$products = Post::query()
->whereHas('user', function ($query) use ($terms) {
foreach ($terms as $term) {
// Loop over the terms and do a search for each.
$query->where('name', 'like', '%' . $term . '%');
}
})
->orWhere(function ($query) use ($terms) {
foreach ($terms as $term) {
$query->where('tags', 'like', '%' . $term . '%');
}
})
->get();
您需要先准备 $terms
数组,然后遍历它并添加 orWhere()
子句。
我刚刚对其进行了测试,对于 whereHas()
闭包,您需要对第一项使用 where()
,对其余部分使用 orWhere()
才能使其正常工作:
$posts = Post::whereHas('user', function($q) use($terms) {
$q->where('name', 'like', '%' . $term .'%');
foreach (array_slice($terms, 1) as $term) {
$q->orWhere('name', 'like', '%' . $term .'%');
}
});
foreach ($terms as $term) {
$posts->orWhere('tags', 'like', '%' . $term . '%');
}
$posts = $posts->get();
如果您决定使用 =
而不是 like
,只需使用 whereIn()
而不是使用一堆 orWhere()
.[=20= 构建查询]
过去几天我在这上面花了很多时间,这是我的解决方案。它与其他这些相似但不同,因此有一天它可能对某人有价值:
我有一个发出 GET 请求的 Vue 组件,所以 $request->get('searchTerms')
来自 <input name="searchTerms">
在 HTML 表单提交中。
我想让用户控制要搜索哪些字段,所以这就是为什么 $search_terms
是要搜索的列数组的原因。
我想要它,所以如果用户搜索 "McDonalds 604",它会过滤记录列表并为该搜索显示两个不同的匹配项。一个匹配 "McDonalds" 对应 business_name
,一个匹配“604”对应 phone_number
的区号。这将确保用户在只知道一些片段的情况下可以获得所有相关信息。
The goal was to iterate over the search terms and also to iterate over the search fields (columns) with a generic formula that could be applied from any number of search terms and columns, dynamic at runtime.
$search_fields = ['project_name', 'business_name', 'phone_number'];
$search_terms = explode(' ', $request->get('searchTerms'));
$query = Campaign::query();
foreach ($search_terms as $term) {
$query->orWhere(function ($query) use ($search_fields, $term) {
foreach ($search_fields as $field) {
$query->orWhere($field, 'LIKE', '%' . $term . '%');
}
});
}
$filtered = $query->get();
我建议通读 Laravel 的查询文档,因为它会让您对这项任务有更好的直觉:https://laravel.com/docs/5.6/queries
在上面的代码中,我们使用了 parameter grouping
,如果您使用 where
与 orWhere
,它会改变算法的特性。
红利小知识
我还强烈建议使用 $query->toSql()
和 $query->getBindings()
测试您的 SQL 语句。您可以将它们放在 $query->get()
的位置,以查看它生成的 SQL 语句的外观以及参数绑定是什么。 getBindings()
将显示 ?
的值在 toSql()
.
中
这是我的控制器
$term = $request->get('q');
// return $request->q;
$products = Post::whereHas('user', function($query) use($term) {
$query->where('name', 'like', '%'.$term.'%');
})->orWhere('tags','LIKE','%'.$term.'%')->get();
return view('pages.search', compact('products','users'));
这对单个关键字搜索很有用。但我想将它用于多个关键字。像 laravel php 等。当我搜索多个值时请指导我,如 abc php laravel 或任何它应该工作的东西。如果标签存在于不同的列中,例如 php 出现在第一列中,而 laravel 出现在下一列中,当我搜索 php laravel 时,它应该向我显示两个列值。
可能有更好的方法来做到这一点,比如使用 CloudSearch/Algolia,但这是一个对我们有用的解决方案:
// Split the terms by word.
$terms = explode(" ", request('q'));
$products = Post::query()
->whereHas('user', function ($query) use ($terms) {
foreach ($terms as $term) {
// Loop over the terms and do a search for each.
$query->where('name', 'like', '%' . $term . '%');
}
})
->orWhere(function ($query) use ($terms) {
foreach ($terms as $term) {
$query->where('tags', 'like', '%' . $term . '%');
}
})
->get();
您需要先准备 $terms
数组,然后遍历它并添加 orWhere()
子句。
我刚刚对其进行了测试,对于 whereHas()
闭包,您需要对第一项使用 where()
,对其余部分使用 orWhere()
才能使其正常工作:
$posts = Post::whereHas('user', function($q) use($terms) {
$q->where('name', 'like', '%' . $term .'%');
foreach (array_slice($terms, 1) as $term) {
$q->orWhere('name', 'like', '%' . $term .'%');
}
});
foreach ($terms as $term) {
$posts->orWhere('tags', 'like', '%' . $term . '%');
}
$posts = $posts->get();
如果您决定使用 =
而不是 like
,只需使用 whereIn()
而不是使用一堆 orWhere()
.[=20= 构建查询]
过去几天我在这上面花了很多时间,这是我的解决方案。它与其他这些相似但不同,因此有一天它可能对某人有价值:
我有一个发出 GET 请求的 Vue 组件,所以 $request->get('searchTerms')
来自 <input name="searchTerms">
在 HTML 表单提交中。
我想让用户控制要搜索哪些字段,所以这就是为什么 $search_terms
是要搜索的列数组的原因。
我想要它,所以如果用户搜索 "McDonalds 604",它会过滤记录列表并为该搜索显示两个不同的匹配项。一个匹配 "McDonalds" 对应 business_name
,一个匹配“604”对应 phone_number
的区号。这将确保用户在只知道一些片段的情况下可以获得所有相关信息。
The goal was to iterate over the search terms and also to iterate over the search fields (columns) with a generic formula that could be applied from any number of search terms and columns, dynamic at runtime.
$search_fields = ['project_name', 'business_name', 'phone_number'];
$search_terms = explode(' ', $request->get('searchTerms'));
$query = Campaign::query();
foreach ($search_terms as $term) {
$query->orWhere(function ($query) use ($search_fields, $term) {
foreach ($search_fields as $field) {
$query->orWhere($field, 'LIKE', '%' . $term . '%');
}
});
}
$filtered = $query->get();
我建议通读 Laravel 的查询文档,因为它会让您对这项任务有更好的直觉:https://laravel.com/docs/5.6/queries
在上面的代码中,我们使用了 parameter grouping
,如果您使用 where
与 orWhere
,它会改变算法的特性。
红利小知识
我还强烈建议使用 $query->toSql()
和 $query->getBindings()
测试您的 SQL 语句。您可以将它们放在 $query->get()
的位置,以查看它生成的 SQL 语句的外观以及参数绑定是什么。 getBindings()
将显示 ?
的值在 toSql()
.