根据查询Elasticsearch中的标准序列返回结果

时间:2016-08-18 09:13:13

标签: elasticsearch

我希望结果与查询的顺序相同。要详细说明这一点,请考虑以下示例。 :

我有ID字段的文档,看起来有点像这样:

{
  {
    "ID": 102,
    "Name": "Mark"
  },
  {
    "ID": 104,
    "Name": "Pete"
  },
  {
    "ID": 101,
    "Name": "Su"
  },
  {
    "ID": 107,
    "Name": "Kate"
  },
  {
    "ID": 106,
    "Name": "Roger"
  }
}

我的疑问是:

{
  "query": {
    "bool": {
      "should": [
        {
          "match": 
          {
            "ID": "101"
          }
        },
        {
          "match": 
          {
            "ID": "104"
          }
        },
        {
          "match": 
          {
            "ID": "107"
          }
        },
        {
          "match": 
          {
            "ID": "102"
          }
        },
        {
          "match": 
          {
            "ID": "106"
          }
        }
      ]
    }
  }
}

现在我希望结果与搜索条件的顺序相同。即:

{
    "ID": 101,
    "Name": "Su"
},
{
    "ID": 104,
    "Name": "Pete"
},
{
    "ID": 107,
    "Name": "Kate"
},
{
    "ID": 102,
    "Name": "Mark"
},
{
    "ID": 106,
    "Name": "Roger"
}

一直试图找到一种方法来做到这一点。它甚至可能吗? 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我认为只使用查询或过滤器就无法实现这种评分机制。

当您的查询构建器构建查询时,这些id的源是如何进入代码的。它们的顺序与您要对文档排序的顺序相同。

如果是,那么我建议用功能评分或基于脚本的评分逻辑来滋养您的查询。你可以使用groovy sandbox或mvel。

{
  "query": {"filtered": {
    "query": {"function_score": {
      "query": {"match_all": {}},
      "functions": [
        {"script_score": {
          "params": {
            "id_list":[103,105,109,101]
          }, 
          "script": " id_list.length -id_list.indexOf(doc['id'].value)"
        }}
      ]
    }}
  }}
}

Scripting in elasticsearch.

Function score in elastic

考虑它就像提供一个数组结构,其中id包含在您希望返回结果的相同顺序中作为函数分数内的脚本分数的参数。 在比较doc字段中文档的id后,将Array.size - index的分数分配给每个文档。 我认为这几乎可以解决你的问题。这不是一个具体的解决方案,而是一个解决方法

注意 - 小心我的群集配置为允许内联脚本执行,默认脚本语言配置为javascript。如果您遵循这种方法,您可能还需要查看您的群集配置