php - 根据用户输入的值在弹性搜索中排序
问题描述
我想按用户输入的顺序获取产品。假设如果用户搜索“Z1234”、“S1234”、“T2344”,那么我想要按特定顺序排列的产品。其中 Z1234 将是第一条记录。如何在弹性搜索中实现这一点。我尝试过使用“脚本”和其他方式,但它不起作用。下面是我的脚本使用示例。
'_script' => [
'script' => "for(i:scoring) { if(doc[\"custom_44\"].value == i.id) return i.score; } return 0;",
"type" => "number",
'params' => [
'scoring' => [
['id'=>'3MS01',"score" => 1],
['id'=>'29xcs',"score" => 2],
]
],
"order" => "asc"
]
我的工作查询正文如下
Array
(
[size] => 20
[from] => 0
[query] => Array
(
[filtered] => Array
(
[filter] => Array
(
[bool] => Array
(
[must] => Array
(
[0] => Array
(
[bool] => Array
(
[should] => Array
(
[0] => Array
(
[query] => Array
(
[span_near] => Array
(
[clauses] => Array
(
[0] => Array
(
[span_multi] => Array
(
[match] => Array
(
[regexp] => Array
(
[custom_44] => .*3MS01.*
)
)
)
)
)
[slop] => 0
[in_order] => 1
)
)
)
[1] => Array
(
[query] => Array
(
[span_near] => Array
(
[clauses] => Array
(
[0] => Array
(
[span_multi] => Array
(
[match] => Array
(
[regexp] => Array
(
[custom_44] => .*29xcs.*
)
)
)
)
)
[slop] => 0
[in_order] => 1
)
)
)
)
)
)
[1] => Array
(
[term] => Array
(
[deleted] => 0
)
)
[2] => Array
(
[terms] => Array
(
[publication_id] => Array
(
[0] => 35627
)
)
)
[3] => Array
(
[term] => Array
(
[custom_61] => 1
)
)
)
)
)
)
)
[sort] => Array
(
[0] => Array
(
[custom_44] => asc
)
)
)
这可以在弹性搜索中实现吗?得到结果后需要排序吗?
解决方案
ElasticSearch 将根据特定字段的评分与您的输入进行比较,对结果进行排序。
例如,如果您搜索“Z1234 S1234 T2344”,它会尝试查找尽可能靠近单个输入和分析器的文档,然后它会根据邻近度分数对结果进行相应的排名。
例如,考虑以下索引:
POST test/doc/
{
"product_name" : "Z1234"
}
POST test/doc/
{
"product_name" : "Z1235"
}
POST test/doc
{
"product_name" : "S1234"
}
POST test/doc
{
"product_name" : "T2344"
}
如果您搜索 "Z1234 S1234 T2344" ,它将根据分数对结果进行排序(结果更接近您的输入),然后将剩余的排序如下(诸如“Z1235”之类的值)
GET test/doc/_search
{
"query": {
"match" : {
"product_name" : {
"query" : "Z1234 S1234 T2344",
"operator" : "OR",
"fuzziness": 1
}
}
}
}
"hits": {
"total": 5,
"max_score": 1.2476649,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "AWViqiCOOSSVvlNCAXVu",
"_score": 1.2476649,
"_source": {
"product_name": "Z1234"
}
},
{
"_index": "test",
"_type": "doc",
"_id": "AWViqlZ2OSSVvlNCAXV7",
"_score": 0.6931472,
"_source": {
"product_name": "T2344"
}
},
{
"_index": "test",
"_type": "doc",
"_id": "AWViqj9UOSSVvlNCAXV2",
"_score": 0.51782775,
"_source": {
"product_name": "S1234"
}
},
{
"_index": "test",
"_type": "doc",
"_id": "AWVir1UeOSSVvlNCAXpB",
"_score": 0.23014566,
"_source": {
"product_name": "Z1235"
}
},
{
"_index": "test",
"_type": "doc",
"_id": "AWVirhwlOSSVvlNCAXkQ",
"_score": 0.23014566,
"_source": {
"product_name": "Z1235"
}
}
]
}
}
现在,如果您不想按分数排序,而是按字段名称排序,则排序的字段应包含 doc 值(默认为 Text 字段)
GET test/doc/_search
{
"query": {
"match": {
"product_name": {
"query": "Z1234 S1234 T2344",
"operator": "OR",
"fuzziness": 1
}
}
},
"sort": [
{
"product_name.keyword": {
"order": "desc"
}
}
]
}
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": null,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "AWVitbfmOSSVvlNCAYA8",
"_score": null,
"_source": {
"product_name": "Z1235"
},
"sort": [
"Z1235"
]
},
{
"_index": "test",
"_type": "doc",
"_id": "AWVita_pOSSVvlNCAYA7",
"_score": null,
"_source": {
"product_name": "Z1234"
},
"sort": [
"Z1234"
]
},
{
"_index": "test",
"_type": "doc",
"_id": "AWVitcPKOSSVvlNCAYBA",
"_score": null,
"_source": {
"product_name": "T2344"
},
"sort": [
"T2344"
]
},
{
"_index": "test",
"_type": "doc",
"_id": "AWVitb1GOSSVvlNCAYA_",
"_score": null,
"_source": {
"product_name": "S1234"
},
"sort": [
"S1234"
]
}
]
}
}
推荐阅读
- javascript - 如何将链接添加到组件的一部分并使其可点击
- pandas - 有条件地连接两个数据帧
- paypal - 自定义 Paypal 登录模板的任何选项
- javascript - 替换 Query 对象的 getPosts 字段时,缓存数据可能会丢失。阿波罗
- sql-server - 由于“CHECKPOINT”,数据库“master”的事务日志已满
- xml - 无法在线性布局中移动 Android Studio 中的按钮
- cmake - 如何在 cmake 中使用浮动 WindRiver 许可证
- java - 重定向所有 html 获取请求以从 ROOT/frontEnd 文件夹而不是 Tomcat 服务器上的 ROOT 获取文件
- ios - 滑动以从通知中心关闭通知时,有什么方法可以获得回调或处理程序?
- docker - Pyomo 在 Docker 上使用 Flask - 找不到求解器“glpk”的可执行文件