ElasticSearch-为4个独立的随机分组组合查询



我对弹性搜索还很陌生(尽管有一些SQL经验(,目前正在努力构建一个合适的查询。我有两个布尔字段isPlayerisEvil,其中一个条目是truefalse。基于此,我想将我的数据集分为4组:

  1. isPlayer:true,isEvil:true
  2. isPlayer:true,isEvil:false
  3. isPlayer:false,isEvil:true
  4. isPlayer:false,isEvil:false

我想在这些组中随机排序,然后将它们附加为一个可以分页的长列表。我想在查询中这样做,因为这看起来像是";正确的";这样做的方法,因为我在SQL中也会做类似的事情。在该列表中,组将按顺序排序,因此首先是组1的所有条目按随机顺序排列,然后是组2的所有条目,然后是第3组的所有条目等。如果给定相同的输入,则排序的随机性是可再现的,因此,如果排序是基于random_score的,理想情况下,我会使用随机性种子。

我可以构建一个查询,但如何组合4个查询?

到目前为止,我已经找到了MultiSearch和Disjunction Max Query。MultiSearch似乎不支持分页。关于Disjunction Max Query,我可能错过了树的森林,但在将子查询彼此附加之前,我很难让它们只在自己内部随机排序。

以下是我现在如何在没有Disjunction Max Query的情况下编写单个查询,以防有帮助:

{
"query": {
"bool": {
"should": [
{
"term": {
"isPlayer": true
}
},
{
"term": {
"isEvil": true
}
}
]
}
}
}

这个问题的解决方案不是进行4个单独的组,而是确保它们都有不同的分数范围并按分数排序。这可以通过不是通过某种匹配标准而是通过脚本得分字段来对命中进行评分来实现。这个字段允许您自己编写返回逻辑分数的代码(默认语言称为"无痛",但我也看到过groovy的例子(。

逻辑相当简单:

  1. 如果isPlayer=true,则在分数上加2分
  2. 如果isEvil=true,则在分数上加4分
  3. 无论哪种方式,在末尾的分数上加一个0到1之间的随机数

这创建了我想要的具有不同分数范围的4组:

  1. isPlayer=true,isEvil=true-->得分范围:6-7
  2. isPlayer=false,isEvil=true-->得分范围:4-5
  3. isPlayer=true,isEvil=false-->得分范围:2-3
  4. isPlayer=false,isEvil=false-->得分范围:0-1

查询如下所示:

"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": """
double score = 0;
if(doc['isPlayer']){
score += 2;
}

if(doc['isEvil']){
score += 4;
}

int partialSeed = 1;
score += randomScore(partialSeed, 'id');
return score;
"""
}
}
}
}

最新更新