【问题标题】:In Elasticsearch, how can I get the whole of a nested field returned without the whole object?在 Elasticsearch 中,如何在没有整个对象的情况下返回整个嵌套字段?
【发布时间】:2016-11-21 07:19:13
【问题描述】:

我有一个映射,其中我有一个嵌套类型,嵌套对象通常包含多个对象,因此如果检索到整个主对象,它就是一个数组。使用搜索请求的“字段”部分,我可以获得主对象的字段,以及来自嵌套对象的字段(作为数组,除非只有一个),但显然不是整个嵌套对象数组。除了获取整个对象(省略字段)之外,还有其他方法吗?

例如:

{ "properties: { "f1": {"type": "string"}, "f2": {"type": "string"}, ... "n": { "type": "nested", "properties": { "n1": {"type": "string"}, "n2": {"type": "string"}, ... } } } }

通常,n 将是一个数组,但可能不会为所有条目设置 n1

此查询有效,但由于数组中的某些对象中缺少 n1,因此没有帮助:

{"query": {"nested": {"path": "n", "query": {"match": {"n.n1","something"}}}}, "fields": ["f1", "n.n1"]}

这不是(“字段 [n] 不是叶字段”),而是我真正想要的:

{"query": {"nested": {"path": "n", "query": {"match": {"n.n1","something"}}}}, "fields": ["f1", "n"]}

但这确实会以检索整个对象为代价,包括(数组)n:

{"query": {"nested": {"path": "n", "query": {"match": {"n.n1","something"}}}}}

当 n 之一中的一个字段匹配时,是否有一些我缺少的查询语法会给我整个数组 n(以及主对象中的至少一个字符串字段),而没有得到整个匹配对象?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我觉得你想要的大概是Inner_Hitshttps://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html#top-level-inner-hits

    基本上,您可以执行一个查询,该查询将只返回与您的查询匹配的嵌套对象,而不是与您的查询匹配的每个“父”对象的所有嵌套对象。

    将它与_source: false 标志结合起来,我认为您或多或少会得到您正在寻找的东西。

    这是一个例子:

      "_source": "false",
      "query": {
            "match": {
              "n.n1": "something"
            }
          },
      "inner_hits": {
      "myname": {
        "path": {
          "n": {
            "query": {
              "match": {
                "n.n1": "something"
              }
            }
          }
        }
      }
    }
    

    顶级查询将为您提供包含n.n1 contains "something" 的任何内部文档的所有父文档。然后,内部查询还将将该数组过滤为仅具有n.n1 contains "something" 的内部文档。如果您实际上根本不想过滤 Inner_hits,即使 n1 为空,您也只想要所有这些,然后只需将内部命中查询更改为 match_all

    这会给你一个类似的回应:

     {
        "_index": "myindex",
        "_type": "mytype",
        "_id": "theid",
        "_score": 1,
        "inner_hits": {
          "myname": {
            "hits": {
              "total": 2,
              "max_score": 2.4890606,
              "hits": [
                {
                  "_index": "myindex",
                  "_type": "mytype",
                  "_id": "2",
                  "_nested": {
                    "field": "n",
                    "offset": 1
                  },
                  "_score": 2.4890606,
                  "_source": {
                    "n1": "something",
                    "n2": "whatever"
                  }
                },
                {
                  "_index": "myindex",
                  "_type": "mytype",
                  "_id": "3",
                  "_nested": {
                    "field": "n",
                    "offset": 0
                  },
                  "_score": 2.4890606,
                  "_source": {
                    "n1": "something",
                    "n2": "great"
                  }
                }
              ]
            }
          }
        }
      }
    

    如果有什么不清楚的地方请告诉我。

    编辑:

    根据我的评论,这里是一个例子:

    {
    
    "fields": ["f1"], 
      "query": {
        "match": {
          "n.n1": "something"
        }
      },
      "inner_hits": {
        "myname": {
          "path": {
            "n": {
              "query": {
               "match_all" : {}
              }
            }
          }
        }
      }
    }
    

    该查询将为您提供所有包含 n.n1 包含“某物”的子文档的所有父文档。 Inner hits 查询将为您提供父母的所有孩子,包括那些 n.n1 不包含“某物”的孩子。 fields 标志将意味着只为父文档返回选定的字段。

    【讨论】:

    • 不幸的是,没有。顾名思义,这只是命中。在我的示例中,当 n 的 any 匹配时,我在整个顶级对象(包括我的示例中的 whole 数组 n)的字段子集之后。我可以得到这个,但只是不要求特定的“字段”,所以它检索到很多不感兴趣的数据。
    • 好吧,您不必设置“source:false”,而且您当然仍然可以对您想要从父级获得的所有其他字段使用“fields :”标志。然后将嵌套查询保留为全部匹配。
    • 但这不是只给我命中的 n,并省略同一对象中的其他 n 吗?
    • 我添加了一个编辑,对不起,也许我完全误解了你想要实现的目标。我认为我提供的查询是您想要的。
    • 是的,谢谢(除了主查询需要“嵌套”才能工作)。我缺少的是 inner_hits 查询基本上独立于主要命中(在该命中的 n 内)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多