我正在编写一个API,该API利用facet 向最终用户推荐产品,具体取决于他们的设置。在用户可以组合来自多个类别的过滤器的意义上,数据是多方面的。更重要的是,返回的结果不应该仅限于精确结果,而是根据查询得分返回X项列表。
数据是专有的,所以我将映射替换为基于任天堂的示例的真实字段,这样我们就可以在获得一些非常需要的Elasticsearch帮助时度过愉快的时光。
示例:用户正在寻找可以播放Mario
和Luigi
的游戏,但Bowser
不应该播放。该游戏应该是SNES
,不应该是NES
:
{
"query": {
"bool": {
"should": [
{
"nested": {
"score_mode" : "sum",
"path": "players",
"query": { "bool": {"must": [
{ "terms": { "players.name": ["Mario", "Luigi"] } }
]}}
}
},
{
"nested": {
"score_mode" : "sum",
"path": "console",
"query": {"bool": {"must": [
{ "terms": { "console.name": ["SNES"] } }
]}}
}
},
{
"nested": {
"score_mode" : "min",
"path": "players",
"query": {"bool": {"must_not": [
{ "terms": { "players.name": ["Bowser"] } }
]}}
}
},
{
"nested": {
"score_mode" : "min",
"path": "console",
"query": {"bool": {"must_not": [
{ "terms": { "console.name": ["NES"] } }
]}}
}
}
]
}
}
}
结果:
"hits": [
{
"_index": "games",
"_type": "game",
"_id": "4aee02d4-6b83-11e8-8938-294f2d4dc7ef",
"_score": 5,
"_source": {
"console": [
{
"name": "SNES"
}
],
"players": [
{
"name": "Luigi"
},
{
"name": "Mario"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "4795963e-6b88-11e8-a4cb-732f847dc805",
"_score": 5,
"_source": {
"console": [
{
"name": "NES"
},
{
"name": "SNES"
}
],
"players": [
{
"name": "Mario"
},
{
"name": "Luigi"
},
{
"name": "Peach"
},
{
"name": "Toad"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "800569c5-6b89-11e8-b27b-f7dae11d9bc9",
"_score": 4,
"_source": {
"console": [
{
"name": "SNES"
}
],
"players": [
{
"name": "Mario"
}
{
"name": "Bowser"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "13325f86-6b89-11e8-bfea-1fe5e2b5a461",
"_score": 4,
"_source": {
"console": [
{
"name": "SNES"
},
{
"name": "NES"
}
],
"players": [
{
"name": "Mario"
},
{
"name": "Bowser"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "256d4dcb-6b86-11e8-b4e0-3fece057ccb0",
"_score": 3,
"_source": {
"console": [
{
"name": "SNES"
}
],
"players": [
{
"name": "Mega Man"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "5bcda1fa-6b87-11e8-a411-e7f5fa3abcdd",
"_score": 3,
"_source": {
"console": [
{
"name": "SNES"
},
{
"name": "NES"
}
],
"players": [
{
"name": "Fox McCloud"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "e3020f5c-6b87-11e8-8cc6-87fc791a9c1a",
"_score": 2,
"_source": {
"console": [
{
"name": "NES"
}
],
"players": [
{
"name": "Kid Icarus"
}
]
}
},
{
"_index": "games",
"_type": "game",
"_id": "48291645-6b83-11e8-a4cb-732f847dc805",
"_score": 2,
"_source": {
"console": [
{
"name": "N64"
}
],
"players": [
{
"name": "James Bond"
}
]
}
}
]
我对得分如何运作感到非常困惑。我已经在我的ES查询中看到了得分类型,但不知道如何使得负面命中排名更低。例如,在游戏13325f86-6b89-11e8-bfea-1fe5e2b5a461
的情况下,为什么匹配2个底片和2个正片的游戏得分为4?
然后,如果我想提升某个类别,例如console
,我就无法弄清楚如何使用terms
来实现这一目标。