簡體   English   中英

ElasticSearch 嵌套查詢過濾器按數組中的第二項

[英]ElasticSearch nested query filter by second item in array

我想按第二個值過濾嵌套字段stats中的組(這里我將其標記為value_filtered )。 stats包含 4 個對象。 我想要數組中第二項大於 0 的所有組( value_filtered > 0 )。 以下文檔示例:

        {
          "group_name": "Group_1",
          "date": "2020-05-20",
          "stats" : [
            {
              "name_en" : "xxx",
              "value" : 45
            },
            {
              "name_en" : "value_filtered",
              "value" : 0
            },
            {
              "name_en" : "vvv",
              "value" : 20
            },
            {
              "name_en" : "zzz",
              "value" : 0.666
            }
          ]
        }

我的方法是使用filter script ,但是由於某些原因它不起作用。 但是相同的腳本不在過濾器中,而是在scripting field工作 - 下面是我的代碼示例:

query = {
    'size': 100,
    '_source': {
        'include': ['group_name']
    },
    "query": {
        "bool": {
            "filter": [
                {
                    'term': {
                        'date': '2020-05-20'
                    }
                }
            ]
        }
    },
    'script_fields': {
        'stats': {
            'script': {
                'lang': 'painless',
                'source': """
                int value_filtered = (int) params._source['metrics'][1].value;
                return value_filtered > 0;            
                """
            }
        }
    }
}

腳本字段腳本過濾器Painless 上下文略有不同。

這就是你所追求的:

{
  "size": 100,
  "_source": {
    "include": [
      "group_name"
    ]
  },
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "date": "2020-05-20"
          }
        },
        {
          "script": {
            "script": {
              "source": """
                def stats_values = doc['stats.value'];
                if (stats_values.size() == 0 || stats_values.length < 2) {
                  return false;
                }
                int value_filtered = (int) stats_values[1]; 
                return value_filtered > 0;
              """
            }
          }
        }
      ]
    }
  }
}

我生成了一些帶有groupstats的索引(為簡單起見,我刪除了日期)只是為了測試腳本過濾器:

映射:

{
  "my_test_stats" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "group" : {
          "type" : "keyword"
        },
        "stats" : {
          "type" : "nested",
          "properties" : {
            "name_en" : {
              "type" : "keyword"
            },
            "value" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
    "settings" : {
      ...
    }
  }
}

我的索引中的三個文檔:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_test_stats",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "group" : "abc",
          "stats" : [
            {
              "name_en" : "xxx",
              "value" : 45
            },
            {
              "name_en" : "value_filtered",
              "value" : 0
            },
            {
              "name_en" : "vvv",
              "value" : 20
            },
            {
              "name_en" : "zzz",
              "value" : 0.666
            }
          ]
        }
      },
      {
        "_index" : "my_test_stats",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "group" : "xyzz",
          "stats" : [
            {
              "name_en" : "xxx",
              "value" : 45
            },
            {
              "name_en" : "value_filtered",
              "value" : 20
            },
            {
              "name_en" : "vvv",
              "value" : 20
            },
            {
              "name_en" : "zzz",
              "value" : 0.666
            }
          ]
        }
      },
      {
        "_index" : "my_test_stats",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "group" : "defg",
          "stats" : [
            {
              "name_en" : "xxx",
              "value" : 45
            },
            {
              "name_en" : "value_filtered",
              "value" : 30
            },
            {
              "name_en" : "vvv",
              "value" : 20
            },
            {
              "name_en" : "zzz",
              "value" : 0.666
            }
          ]
        }
      }
    ]
  }
}

調整后的查詢:

GET /my_test_stats/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "script": {
            "script": {
              "source": """
                def stats_values = doc['stats.value'];
                if (stats_values.size() == 0 || stats_values.length < 2) {
                  return false;
                }
                int value_filtered = (int) stats_values[1]; 
                return value_filtered > 0;
              """
            }
          }
        }
      ]
    }
  }
}

結果是空列表,但應該是 2 條記錄。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM