Elasticsearch - 对嵌套对象列表进行脚本过滤

bet*_*o86 5 elasticsearch elasticsearch-painless

我试图弄清楚如何解决我的 ES 5.6 索引遇到的这两个问题。

"mappings": {
    "my_test": {
        "properties": {
            "Employee": {
                "type": "nested",
                "properties": {
                    "Name": {
                        "type": "keyword",
                        "normalizer": "lowercase_normalizer"
                    },
                    "Surname": {
                        "type": "keyword",
                        "normalizer": "lowercase_normalizer"
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要创建两个单独的脚本过滤器:

1 - 过滤员工数组大小为 == 3 的文档

2 - 过滤数组的第一个元素具有“名称”==“约翰”的文档

我试图迈出一些第一步,但我无法遍历列表。我总是有一个空指针异常错误。

{
  "bool": {
    "must": {
      "nested": {
        "path": "Employee",
        "query": {
          "bool": {
            "filter": [
              {
                "script": {
                  "script" :     """

                   int array_length = 0; 
                   for(int i = 0; i < params._source['Employee'].length; i++) 
                   {                              
                    array_length +=1; 
                   } 
                   if(array_length == 3)
                   {
                     return true
                   } else 
                   {
                     return false
                   }

                     """
                }
              }
            ]
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Val*_*Val 1

1 - 过滤员工数组大小 == 3 的文档

对于第一个问题,最好的办法是添加另一个包含数组NbEmployees中项目数的根级字段(例如 )Employee,以便您可以使用range查询而不是昂贵的script查询。

然后,每当您修改Employee数组时,您也会NbEmployees 相应地更新该字段。效率更高了!

2 - 过滤数组第一个元素为“Name”==“John”的文档

关于这一点,您需要知道嵌套字段在 Lucene 中是单独的(隐藏)文档,因此无法在同一个查询中一次访问所有嵌套文档。

如果您知道需要检查查询中第一个员工的姓名,只需添加另一个根级字段FirstEmployeeName并对该字段运行查询即可。