簡體   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