【问题标题】:Elasticsearch: Query nested object contained within an objectElasticsearch:查询对象中包含的嵌套对象
【发布时间】:2016-01-08 02:10:10
【问题描述】:

我正在努力构建一个查询,我可以在其中对文档的子对象进行嵌套搜索。

假设我有以下索引/映射:

curl -XPOST "http://localhost:9200/author/" -d '
{
    "mappings": {
        "item": {
            "properties": {
                "books": {
                    "type": "object",
                    "properties": {
                        "data": {
                            "type": "nested"
                        }
                    }
                }
            }
        }
    }
}
'

以及索引中的以下2个文档:

{
    "id": 1,
    "name": "Robert Louis Stevenson",
    "books": {
        "count": 2,
        "data": [
            {
                "id": 1,
                "label": "Treasure Island"
            },
            {
                "id": 3,
                "label": "Dr Jekyll and Mr Hyde"
            }
        ]
    }
}

{
    "id": 2,
    "name": "Philip K. Dick",
    "books": {
        "count": 1,
        "data": [
            {
                "id": 4,
                "label": "Do Android Dream of Electric Sheep"
            }
        ]
    }
}

我有一系列图书 ID,比如 [1,4];我将如何编写一个查询,该查询对作者姓名进行关键字搜索,并且仅当他们在数组中写了一本书时才返回它们?

我还没有设法得到一个不会引起某种查询parse_exception 的查询,但作为一个起点,这是我查询的当前迭代 - 也许很明显我哪里出错了?

{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "label": "Louis"
                }
            }
        },
        "nested": {
            "path": "books.data",
            "query": {
                "bool": {
                    "must": {
                        "terms": {
                            "books.data.id": [
                                1,
                                4
                            ]
                        }
                    }
                }
            }
        }
    },
    "from": 0,
    "size": 8
}

在上述情况下,我希望将 Robert Louis Stevenson 先生的文件归还,因为他的名字包含 Louis 并且他写了书 ID 1

不管怎样,我得到的当前错误如下所示:

{
   "error": {
      "root_cause": [
         {
            "type": "parse_exception",
            "reason": "failed to parse search source. expected field name but got [START_OBJECT]"
         }
      ],
      "type": "search_phase_execution_exception",
      "reason": "all shards failed",
      "phase": "query",
      "grouped": true,
      "failed_shards": [
         {
            "shard": 0,
            "index": "author",
            "node": "sCk3su4YSnqhvdTGjOztlw",
            "reason": {
               "type": "parse_exception",
               "reason": "failed to parse search source. expected field name but got [START_OBJECT]"
            }
         }
      ]
   },
   "status": 400
}

这让我觉得我的“嵌套”对象完全错了,但文档表明我是对的!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    你说得差不多了,nested 查询必须简单地位于bool 内,就像下面的查询一样。此外,match 查询需要在 name 字段上进行,因为这是存储作者姓名的位置:

    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "Louis"
              }
            },
            {
              "nested": {
                "path": "books.data",
                "query": {
                  "bool": {
                    "must": {
                      "terms": {
                        "books.data.id": [
                          1,
                          4
                        ]
                      }
                    }
                  }
                }
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 8
    }
    

    【讨论】:

    • 谢谢,这让我走上了正轨。我还需要将我的 mustnested 对象放入一个数组中......微妙!
    • 是的先生,很高兴它有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多