簡體   English   中英

使用嵌套字段嵌套值過濾文檔 Elastic Search

[英]Filtering Documents with nested field nested value Elastic Search

我的數據演示:

{
  "id": "1",
  "username": "demo",
  "email": "dasdasdas@dsadas",
  "number": "000111000",
  "createdDate": "2022-07-13",
  "educations": [
    {
      "name": "test01",
      "score": "5.00",
      "config": {
        "configName": "Ha Ha",
        "isVisible": true
      }
    },
    {
      "name": "demo02",
      "score": "4.50",
      "config": {
        "configName": "Hi Hi",
        "isVisible": false
      }
    },
    {
      "name": "demo03",
      "score": "4.00",
      "config": {
        "configName": "Hu Hu",
        "isVisible": true
      }
    }
  ]
}

現在,我想顯示educatations.config.isVisible = true的所有數據

我嘗試的java代碼如下:

boolQueryBuilder = boolQueryBuilder.must(
                       nestedQuery("educations.config", 
                           termQuery("educations.config.isVisible", true),
                           ScoreMode.Total));

但它正在返回所有數據。

誰能幫我查詢一下。

好吧,您提供的演示數據由一個文檔組成,嵌套數組中包含您要過濾的數據。

默認情況下,Elasticsearch 將始終返回與查詢匹配的所有完整文檔。 由於其中一個嵌套字段與您的查詢匹配,因此將返回完整的源。 這是正確和預期的行為。

如果您想要一個文檔的部分命中,有幾個選項,盡管它們都不能產生您想要的結果:

雖然您可以使用_source_includes和/或_source_excludes從 Elasticsearch 獲取部分結果,但您不能有條件地這樣做。 即你可以

GET test_index/_search?_source_excludes=educations

但這將從結果中刪除所有educations領域,而不是基於您的問題所涉及的條件。

一種獲得所需內容的方法是在嵌套查詢中使用inner_hits

GET test_index/_search
{
  "query": {
    "nested": {
      "path": "educations.config",
      "query": {
        "match": {"educations.config.isVisible": true}
      },
      "inner_hits": {} 
    }
  }
}

每個hit都會有一個額外的部分inner_hits ,其中僅包含滿足搜索條件的嵌套字段的(子)命中。 默認情況下, inner_hits中返回的命中的_source是相對於_nested元數據的。 所以在上面的例子中,每個嵌套命中只返回config部分,而不是頂層文檔的整個源:

"_source" : {
  "id" : "1",
  "username" : "demo",
  "email" : "dasdasdas@dsadas",
  "number" : "000111000",
  "createdDate" : "2022-07-13",
  "educations" : [
    {
      "name" : "test01",
      "score" : "5.00",
      "config" : {
        "configName" : "Ha Ha",
        "isVisible" : true
      }
    },
    {
      "name" : "demo02",
      "score" : "4.50",
      "config" : {
        "configName" : "Hi Hi",
        "isVisible" : false
      }
    },
    {
      "name" : "demo03",
      "score" : "4.00",
      "config" : {
        "configName" : "Hu Hu",
        "isVisible" : true
      }
    }
  ]
},
"inner_hits" : {
  "educations.config" : {
    "hits" : {
      "total" : {
        "value" : 2,
        "relation" : "eq"
      },
      "max_score" : 0.4700036,
      "hits" : [
        {
          "_index" : "test_index",
          "_type" : "_doc",
          "_id" : "dQSz94EBbpRrdmjWWpzK",
          "_nested" : {
            "field" : "educations.config",
            "offset" : 0
          },
          "_score" : 0.4700036,
          "_source" : {
            "configName" : "Ha Ha",
            "isVisible" : true
          }
        },
        {
          "_index" : "test_index",
          "_type" : "_doc",
          "_id" : "dQSz94EBbpRrdmjWWpzK",
          "_nested" : {
            "field" : "educations.config",
            "offset" : 2
          },
          "_score" : 0.4700036,
          "_source" : {
            "configName" : "Hu Hu",
            "isVisible" : true
          }
        }
      ]
    }
  }
}

對於 java 解決方案,請檢查NestedQueryBuilder返回的QueryBuilders.nestedQuery以便在那里配置inner_hits 以下關於Java api 中 Elasticsearch 內部命中的SO 帖子也可能有所幫助。

您還可以將兩者( _source_excludeinner_hits )結合起來,以使您的響應更加緊湊,假設education也是nested類型:

GET test_index/_search?_source_excludes=educations
{
  "query": {
    "nested": {
      "path": "educations",
      "query": {
        "match": {"educations.config.isVisible": true}
      },
      "inner_hits": {} 
    }
  }
}

暫無
暫無

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

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