查询嵌套对象时,Elasticsearch查询无法返回结果

时间:2018-01-10 12:09:56

标签: elasticsearch

我有一个看起来像这样的对象:

{
  "id": 123,
  "language_id": 1,
  "label": "Pablo de la Pena",
  "office": {
    "count": 2,
    "data": [
      {
        "id": 1234,
        "is_office_lead": false,
        "office": {
          "id": 1,
          "address_line_1": "123 Main Street",
          "address_line_2": "London",
          "address_line_3": "",
          "address_line_4": "UK",
          "address_postcode": "E1 2BC",
          "city_id": 1
        }
      },
      {
        "id": 5678,
        "is_office_lead": false,
        "office": {
          "id": 2,
          "address_line_1": "77 High Road",
          "address_line_2": "Edinburgh",
          "address_line_3": "",
          "address_line_4": "UK",
          "address_postcode": "EH1 2DE",
          "city_id": 2
        }
      }
    ]
  },
  "primary_office": {
    "id": 1,
    "address_line_1": "123 Main Street",
    "address_line_2": "London",
    "address_line_3": "",
    "address_line_4": "UK",
    "address_postcode": "E1 2BC",
    "city_id": 1
  }
}

我的Elasticsearch映射如下所示:

"mappings": {
  "item": {
    "properties": {
      "office": {
        "properties": {
          "data": {
            "type": "nested",
          }
        }
      }
    }
  }
}

我的Elasticsearch查询看起来像这样:

GET consultant/item/_search
{
  "from": 0,
  "size": 24,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "language_id": 1
          }
        },
        {
          "term": {
            "office.data.office.city_id": 1
          }
        }
      ]
    }
  }
}

这会返回零结果,但是,如果我删除第二个term并仅将其保留为language_id子句,则它会按预期工作。

我确定这是因为我对嵌套对象如何扁平化的误解,但我没有想法 - 我已尝试过各种查询排列和映射。

非常感谢任何指导。我使用的是Elasticsearch 6.1.1。

1 个答案:

答案 0 :(得分:2)

我不确定您是否需要整个记录,此解决方案会为每条记录提供language_id:1并且具有office.data.office.id:1值。

GET consultant/item/_search
{
  "from": 0,
  "size": 100,
  "query": {
    "bool":{
      "must": [
        {
          "term": {
            "language_id": {
              "value": 1
            }
          }
        },
        {
          "nested": {
            "path": "office.data",
            "query": {
              "match": {
                      "office.data.office.city_id": 1
              }
            }
          }
        }
      ]
    }
  }
}

我在测试索引中放了3个不同的记录,用于打击虚假命中,一个使用不同的language_id,另一个使用不同的office ID,只返回匹配的一个。
如果您只需要办公室数据,那就有点不同但仍然可以解决。