我正在使用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
}
]
}
}
]
Edit1:对于嵌套字段,您需要使用嵌套查询,不能直接在这些字段上运行搜索。
{
"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
}
}
]
}
}
}
}
]
}
}
}
Edit2:仅考虑嵌套查询的得分,您可以提高得分,以便使与嵌套得分匹配的文档得分更高。如果您不希望多重比赛获得任何分数。您可以将其放置在constant_score中,将其提升为0,与此匹配的文档将获得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
}
}
]
}
}
}
}
]
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句