我一直在努力表达我试图用Elasticsearch解决的当前逻辑问题,我认为我有一个很好的方法来表示它。
假设我正在构建一个 API,以便根据用户的偏好对马里奥赛车角色进行排序。用户可以列出他们喜欢的角色,以及他们不喜欢的角色。这是数据集:
{character: {name: "Mario", weight: "Light"}},
{character: {name: "Luigi", weight: "Medium"}},
{character: {name: "Peach", weight: "Light"}},
{character: {name: "Bowser", weight: "Heavy"}},
{character: {name: "Toad", weight: "Light"}},
{character: {name: "Koopa", weight: "Medium"}}
用户输入他们喜欢Mario
和Luigi
,不喜欢Bowser
。使用 Elasticsearch,我如何为用户对这些数据进行排序,以便返回如下列表:
[Mario (+), Luigi (+), Peach, Toad, Koopa, Bowser (-)]
*为了便于阅读,那里有优点和缺点。
这将返回用户前面的顶级选择,中间返回他们同意的选择,最后返回他们不喜欢的选择。不得不使用嵌套查询真的让我感到困惑。
改进查询,假设有一个团队模式,其中每个团队由两个人一组组成,由游戏在以下对中确定:
[Luigi (+), Bowser (-)]
[Mario (+), Peach]
[Toad, Koopa]
如何确保我不会过滤掉包含Bowser
的团队,但仍对结果进行加权,以便如下所示:
[Mario (+), Peach]
[Toad, Koopa]
[Luigi (+), Bowser (-)]
或者,[Luigi, Bowser]
真的应该排在第二位吗?
我对在 Elasticsearch 中构建这样的复杂查询感到非常困惑,并希望得到任何帮助。
根据您的映射,
类似于GET /characters/_search
{
"sort":[
"_score"
],
"query":{
"bool":{
"should":[
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Mario"
}
},
"boost":2.0
}
},
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Luigi"
}
},
"boost":2.0
}
},
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Peach"
}
},
"boost":1.0
}
},
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Toad"
}
},
"boost":1.0
}
},
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Koopa"
}
},
"boost":1.0
}
},
{
"constant_score":{
"filter":{
"term":{
"name.keyword":"Bowser"
}
},
"boost":0
}
}
]
}
}
}
应该工作。 PS:如果您有嵌套映射,则用嵌套查询子句将布尔查询括起来并调整字段名称路径。若要仅返回 name 字段_source请在查询之前添加子句,并将名称路径作为值。
首先我得说 - 恕我直言,为此使用 Elasticsearch 是大材大用。对于此计算,您可能应该使用更简单的内存数据结构。
假设您决定使用 Elasticsearch 实现这一点,我会做以下事情:
1( 使用此映射将每个字符表示为文档 -
PUT game/characters/_mapping
{
"properties": {
"name":{
"type": "keyword"
},
"weight": {
"type": "keyword"
}
}
}
2(每个角色看起来像这样:
PUT game/characters/boswer
{
"name": "bowser",
"weight": "heavy"
}
3(然后,您可以按喜欢的方式获取它们,类似于@sramalingam24建议的方式。请注意,提升必须是非负的,因此您需要将角色的可爱度"规范化"到高于零的范围:
GET game/characters/_search
{
"size": 100,
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"term": {
"name": "Peach"
}
},
"boost": 2
}
},{
"constant_score": {
"filter": {
"term": {
"name": "Mario"
}
},
"boost": 2
}
},{
"constant_score": {
"filter": {
"term": {
"name": "Toad"
}
},
"boost": 1
}
},{
"constant_score": {
"filter": {
"term": {
"name": "Bowser"
}
},
"boost": 0
}
},
]
}
}
}
祝你好运!