我用的是Elasticsearch 7.6
我在餐厅索引中有如下文档:
"name" : "ABC restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 23
},
{
"name" : "rice",
"count" : 10 }
]
计数表示收到的订单数。
当客户在网站上按菜单名称搜索时,我想给几家餐馆中菜单数量高的餐厅打高分,并将其显示在搜索结果的顶部。
要做到这一点,似乎有必要知道无痛脚本中每个文档中匹配的菜单。
我想知道这是可能的。如果是这样,我该怎么做?
更新感谢大家的回答@jaspreet chahal
我做了这样的索引:
PUT restaurant
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"menu":{
"type": "nested",
"properties": {
"name": {"type": "text"},
"count": {"type": "integer"}
}
}
}
}
}
POST /restaurant/_doc/1
{
"name": "ABC Restaurant",
"menu": [
{"name": "chicken", "count": 3},
{"name": "cake", "count": 5}
]
}
POST /restaurant/_doc/2
{
"name": "TEST Restaurant",
"menu": [
{"name": "chicken", "count": 10},
{"name": "cake", "count": 7},
{"name": "rice", "count": 2}
]
}
POST /restaurant/_doc/3
{
"name": "Good Restaurant",
"menu": [
{"name": "chicken", "count": 20},
{"name": "cake", "count": 13},
{"name": "rice", "count": 5}
]
}
我想做的是在使用多重匹配时,根据匹配的菜单计数获得总分,如下所示:
GET restaurant/_search
{
"query": {
"bool": {
"must": [
{
"function_score": {
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "chicken",
"type": "cross_fields",
"fields": [
"menu.name",
"name"
],
"operator": "and"
}
}
]
}
},
"boost_mode": "replace",
"functions": [
{
"field_value_factor": {
"field": "menu.count",
"missing": 0
}
}
]
}
}
]
}
}
}
但是上面的查询没有得到任何结果。
为了让它工作,我在菜单映射中添加了“include_in_root:True”。但在这种情况下,我不能得到适当的分数..(似乎不管搜索词如何,都获得了菜单计数的最低分数)
请问如何让这个工作如我所愿?谢谢!
再次更新。
我已将多重匹配添加到您的查询中
GET restaurant/_search
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "Good Restaurant chicken",
"type": "cross_fields",
"fields": [
"menu.name",
"name"
]
}
},
{
"nested": {
"path": "menu",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
{
"match": {
"menu.name": {
"query": "Good Restaurant chicken",
"operator": "or"
}
}
}
]
}
},
"boost_mode": "replace",
"functions": [
{
"field_value_factor": {
"field": "menu.count",
"missing": 0
}
}
]
}
}
}
}
]
}
}
}
所有结果都很好!但是分数受到多场比赛查询的影响。
这是查询的结果:
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 21.11436,
"hits" : [
{
"_index" : "restaurant",
"_type" : "_doc",
"_id" : "3",
"_score" : 21.11436,
"_source" : {
"name" : "Good Restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 20
},
{
"name" : "cake",
"count" : 13
},
{
"name" : "rice",
"count" : 5
}
]
}
},
{
"_index" : "restaurant",
"_type" : "_doc",
"_id" : "2",
"_score" : 10.133532,
"_source" : {
"name" : "TEST Restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 10
},
{
"name" : "cake",
"count" : 7
},
{
"name" : "rice",
"count" : 2
}
]
}
},
{
"_index" : "restaurant",
"_type" : "_doc",
"_id" : "1",
"_score" : 3.1335313,
"_source" : {
"name" : "ABC Restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 3
},
{
"name" : "cake",
"count" : 5
}
]
}
}
]
}
}
非常感谢您的回答:)
您可以使用function_score根据计数值给嵌套文档更高的分数。
查询:
{
"query": {
"nested": {
"path": "menu",
"query": {
"function_score": {
"score_mode": "sum",
"boost_mode": "replace",
"query": {
"match": {
"menu.name": "chicken"
}
},
"functions": [
{
"field_value_factor": {
"field": "menu.count"
}
}
]
}
}
}
}
}
结果:
"hits" : [
{
"_index" : "index63",
"_type" : "_doc",
"_id" : "tA8IPHIBzLrvZDnz-ghE",
"_score" : 23.0,
"_source" : {
"name" : "ABC restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 23
},
{
"name" : "rice",
"count" : 10
}
]
}
},
{
"_index" : "index63",
"_type" : "_doc",
"_id" : "tQ8JPHIBzLrvZDnz-AiA",
"_score" : 20.0,
"_source" : {
"name" : "XYZ restaurant",
"menu" : [
{
"name" : "chicken",
"count" : 20
},
{
"name" : "rice",
"count" : 8
}
]
}
}
]
编辑1:对于需要使用嵌套查询的嵌套字段,不能直接对这些字段运行搜索。
{
"query": {
"bool": {
"should": [
{
"match": {
"name": {
"operator": "and",
"query": "chicken"
}
}
},
{
"nested": {
"path": "menu",
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"menu.name": {
"query": "chicken",
"operator": "and"
}
}
}
]
}
},
"boost_mode": "replace",
"functions": [
{
"field_value_factor": {
"field": "menu.count",
"missing": 0
}
}
]
}
}
}
}
]
}
}
}
< b >编辑2:要仅考虑嵌套查询的得分,您可以给它更高的提升,以便匹配您的嵌套得分的文档得分更高。如果你不想让你的多场比赛有任何分数。你可以把它放在constant _ score 0 boost中,匹配它的文档将得到0分
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"multi_match": {
"query": "Good Restaurant chicken",
"type": "cross_fields",
"fields": [
"name"
]
}
},
"boost": 0
}
},
{
"nested": {
"path": "menu",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
{
"match": {
"menu.name": {
"query": "Good Restaurant chicken",
"operator": "or"
}
}
}
]
}
},
"boost_mode": "replace",
"functions": [
{
"field_value_factor": {
"field": "menu.count",
"missing": 0
}
}
]
}
}
}
}
]
}
}
}
以下是我的查询的简化版本: 希望有办法解决这个... 提前感谢你的帮助
问题内容: 使用elasticsearch,我试图将计算出的字段添加到地理搜索中。我只想在搜索文档中附加一个额外的计算字段,但是当我通过“ script_fields”添加计算字段时,仅返回该字段。 我尝试添加通配符字段部分,但它不会影响结果。 如何使此查询返回添加了额外计算字段的? 问题答案: 不建议检索字段,而应使用源过滤。 所以,代替这个 用这个:
我正在Node.js中编写一个RESTAPI,使用Mongoose访问MongoDB后端数据库。我想提供一个APIendpoint,它返回与特定variationStatus匹配的数组对象数量的计数。 这是我到目前为止得到的,但它给了我一个空洞的回答。。。 这是我的模型。。。 有人帮我吗? 谢谢
在elasticsearch中,假设我有如下文档 有一个用例,如果我在搜索栏中键入“Bio”,我应该从elasticsearch中获得匹配的字段值和字段名。 对于本例, 输入:“生物” 预期产出: 我应该使用什么类型的查询?我可以想到使用NGram标记器,然后使用匹配查询。但是,我不确定如何只获得匹配的字段值(而不是整个文档)和相应的字段名作为输出。
在Elasticsearch 6.2中,我有一个索引,其中有两个时间戳字段,如下所示: 在我无痛的内联脚本中,对于一些计算,我想将它们(和)转换为此字符串格式()。任何想法怎么能做到?我无法在ES官方文档中找到任何格式化文档。
问题内容: 我正在尝试创建一个脚本字段,该脚本字段将计算两个时间戳之间的时间差,然后在该脚本字段上聚合一个。 我首先尝试: 在合计平均值下产生价值。 然后我尝试了: 生成了一条错误消息,内容为:“在映射中找不到[timedifference]的字段” 问题答案: 简单地将脚本移到聚合上怎么样?