繁体   English   中英

如何使用过滤器脚本迭代elasticsearch中的嵌套数组?

[英]How to iterate through a nested array in elasticsearch with filter script?

我正在尝试在 elasticsearch 中过滤嵌套字段。 嗯,我需要根据某些规则返回某些文件。 要重现我遇到的错误,您可以参考以下示例:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}
PUT my-index-000001/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "John",
      "last": "Smith"
    },
    {
      "first": "Alice",
      "last": "White"
    }
  ]
}

可以看出,我们有一个对象数组(嵌套)。

我需要在可以遍历用户数组的嵌套字段上应用脚本。

例如我试过这个:

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "filter": [
            {
              "script": {
                "script": {
                  "inline": """
                  def users = doc['user'];
                  for ( int i = 0; i < users.size(); i++ ) {
                    
                  }
                  return true;
                  """
                }
              }
            }
          ]
        }
      }
    }
  }
}

我收到此错误

{
  ...
          "script_stack" : [
            "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:90)",
            "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:41)",
            "users = doc['user'];\n                  ",
            "            ^---- HERE"
          ],
          ...
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "No field found for [user] in mapping with types []"
          }
        }
      }
    ]
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

弹性搜索 7.7 版

这是可能的吗? 我已经查看了一些答案,但我不清楚。

嵌套文档很强大,因为您保留了某些属性连接,但有一个缺点,就是不能像这里讨论的那样迭代它们。


话虽如此,您可以使用copy_to功能展平users属性, copy_to所示:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user__first_flattened": {
        "type": "keyword"
      },
      "user": {
        "type": "nested",
        "properties": {
          "first": {
            "type": "keyword",
            "copy_to": "user__first_flattened"
          }
        }
      }
    }
  }
}

然后

PUT my-index-000001/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "John",
      "last": "Smith"
    },
    {
      "first": "Alice",
      "last": "White"
    }
  ]
}

现在您可以访问字段值并可以遍历它们(如果需要,还可能使用循环索引来帮助定位/识别正确的“嵌套”子文档。)这仅在您遍历字段的假设下有效这在每个嵌套子文档中表示,以便您的循环不会被缩短:

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "script": {
            "script": {
              "inline": """
                  def users = doc.user__first_flattened;
                  // users == [Alice, John]
                  for ( int i = 0; i < users.size(); i++ ) {
                    
                  }
                  return true;
                  """
            }
          }
        }
      ]
    }
  }
}

请注意,我们不再进行nested查询 b/c 我们在该上下文之外并在根中获得了我们的扁平字段。


还值得知道的是,您可以用include_in_root替换copy_to ,这在这里同样有用。

给定父文档的嵌套文档列表在嵌套上下文中不可用。 因此 'doc['user']' 在脚本中给你一个例外。 但是,可以按如下方式访问单个嵌套文档:

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "script": {
          "script": "doc['user.first.keyword']=='John'" // <==== This can be done.
        }
      }
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM