Elasticsearch必须具有某些值,而不能所有其他值

时间:2018-11-24 13:21:10

标签: arrays node.js elasticsearch search

所以我有一个具有以下映射的索引:

{
"tests": {
    "mappings": {
        "test": {
            "properties": {
                "arr": {
                    "properties": {
                        "name": {
                            "type": "long"
                        }
                    }
                }
            }
        }
    }
}

我有3个文档,其中“ arr”字段具有以下值:

  1. arr: [{name: 1}, {name: 2}, {name: 3}]
  2. arr: [{name: 1}, {name: 2}, {name: 4}]
  3. arr: [{name: 1}, {name: 2}]

我想以一种可以找到所有名称值都在名称数组中的文档的方式进行搜索。但是,文档并不需要具有数组的所有值,如果文档中没有数组中的一个值,那么文档就不好。

例如:

  1. 如果我的姓名数组为[1,2],那么我只想要文档3,但我都拥有它们
  2. 如果我的名称数组是[1,2,3],那么我想要文档1和3,但是我只有文档1和must,而所有文档都有should
  3. 如果我的名称数组为[1,2,4],那么我想要文档2和3,但是我只有文档2和must,而所有文档都包含should
  4. 如果我的名字数组是[1],那么我不需要任何文档,但我拥有所有的文件

这里的数组很小,在我的项目中,文档中的数组更大,比较的数组也是如此。

因此,具体地说,我需要使用以下方式进行搜索:

  1. 文档中的所有名称都在名称数组中
  2. 文档不需要名称数组中的所有值

提前谢谢

1 个答案:

答案 0 :(得分:2)

使用脚本(无映射更改)

无需更改已存在的内容。

我想出了以下脚本。我认为核心逻辑在于脚本,我认为这是不言自明的。

POST test_index_arr/_search
{
  "query":{
    "bool": {
      "filter": { 
        "script": {
          "script": {
            "source" : """
              List myList = doc['arr.name'];
              int tempVal = myList.size();
              for(int i=0; i<params.ids.size(); i++){
                long temp = params.ids.get(i);
                if(myList.contains(temp))
                {
                  tempVal = tempVal - 1;
                }

                if(tempVal==0){
                  break;
                }
              }

              if(tempVal==0)
                return true;
              else
                return false;
            """,
            "lang"   : "painless",
            "params": {
              "ids": [1,2,4]
            }
          }
        }
      }
    }
  }
}

因此脚本执行的操作是,检查文档是否在输入中以arr的形式包含其所有编号,如果是,它将返回该文档。

在上面的查询中, "ids": [1,2,4] 部分用作输入。您需要根据需要在此处添加/删除/更新值。

希望有帮助!