繁体   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