node.js - 弹性搜索查询为给定关键字选择最相关的数据
问题描述
我有搜索查询来从弹性搜索数据库中获取数据。查询如下
GET /v_entity_master/_search
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "(*gupta*)",
"fields": [
"id","name","mobile"
]
}
},
{
"query_string": {
"query": "*7542*",
"fields": [
"id","name","mobile"
]
}
}
]
}
}
}
此查询返回
{
"id":34501,
"name": "sree gupta",
"mobile":"98775421
},
{
"id":12302,
"name": "gupta",
"mobile":"98775422
}
但我需要的是,给定搜索关键字的完全匹配应该在第一个结果中
预期输出为 ,
{
"id":12302,
"name": "gupta",
"mobile":"98775422
},{
"id":34501,
"name": "sree gupta",
"mobile":"98775421
}
请分享您的建议和想法来解决这个问题。提前致谢
解决方案
那么首先,为什么要在 id 和 mobile (phone?) 字段中搜索“( gupta )” ?根据您分享的两个结果,它们是数字字段,那么您的意图是什么?
第二个必须条款也有同样的问题。我从来没有遇到过包含数值的人的真实姓名......
我也不明白你为什么在第一个必须条款中使用通配符。我假设您想要进行全文搜索。所以你可以简单地使用匹配查询。
现在到你的实际问题:
我在我的测试集群中创建了一个索引,并将您显示为文档的两个响应编入索引。这是我执行查询时的响应:
{
...
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 2.0,
"hits" : [
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "1",
"_score" : 2.0,
"_source" : {
"id" : 12302,
"name" : "gupta",
"mobile" : "98775422"
}
},
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "2",
"_score" : 2.0,
"_source" : {
"id" : 34501,
"name" : "sree gupta",
"mobile" : "98775421"
}
}
]
}
}
请注意,两个文档具有相同的分数。那是因为您在搜索查询中指定了通配符。
现在让我们修改您的查询:
GET gupta/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "gupta"
}
},
{
"query_string": {
"query": "*7542*",
"fields": ["mobile"]
}
}
]
}
}
}
主要区别在于此查询使用匹配查询来执行全文搜索。由于您的文本字段已被分析,因此您无需指定任何通配符。
这将返回以下内容:
{
...
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.2111092,
"hits" : [
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.2111092,
"_source" : {
"id" : 12302,
"name" : "gupta",
"mobile" : "98775422"
}
},
{
"_index" : "gupta",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.160443,
"_source" : {
"id" : 34501,
"name" : "sree gupta",
"mobile" : "98775421"
}
}
]
}
}
现在这两个文档由于Field length normalization有不同的分数。如本文所述,弹性搜索对在总术语数较少的字段中找到的术语匹配进行评分 将比在具有大量术语的字段中找到的匹配更重要。
我希望我能帮助你。
推荐阅读
- python - | Python - Tkinter | 更改按钮单击时不同小部件的颜色
- clang - 如何在 LLVM 传递中插入存储变量地址的指令?
- java - 如何从java servlet中的javascript http请求获取二进制数据或blob,在formdata中请求有效负载
- angular - Angular 在显示网站前几秒钟加载白屏
- django - 如何在 Live 服务器上部署 django 项目?
- javascript - Formdata 维度数组追加
- html - 无法向菜单添加过渡
- mysql - 登录/注册表单只允许每个人使用 MYSQL 登录一次
- php - Laravel - 使用子查询创建模型
- go - 如果未提供证书,单元测试 tls.LoadX509KeyPair 将失败