在数组中按需搜索

时间:2019-04-08 17:33:18

标签: elasticsearch

我正在尝试在数组内实现“按类型搜索”查询。 这是文档的结构:

{
  "guid": "6f954d53-df57-47e3-ae9e-cb445bd566d3",
  "labels":
  [
    {
      "name": "London",
      "lang": "en"
    },
    {
      "name": "Llundain",
      "lang": "cy"
    },
    {
     "name": "Lunnainn",
     "lang": "gd"
    }
  ]
}

到目前为止,这是我自带的:

{
  "query": {
  "multi_match": {
  "fields": ["labels.name"],
  "query": name,
  "type": "phrase_prefix"
  }
}

完全按照要求工作。 问题是我也想按语言搜索。

我尝试过的是:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": ["labels.name"],
            "query": "london",
            "type": "phrase_prefix"
          }
        },
        {
          "term": {
            "labels.lang": "gd"
          }
        }
      ]
    }
  }
}

,但是这些查询作用于数组的单独值。 因此,例如,我只想搜索威尔士语(cy)。这意味着我包含城市名称的查询应仅与“ lang”标记上具有“ cy”的值匹配。 如何编写此类查询?

2 个答案:

答案 0 :(得分:0)

ElasticSearch在内部将嵌套的JSON对象展平,因此它无法关联lang数组中特定元素的namelabels。如果您需要这种相关性,则需要对文档进行不同的索引编制。

执行此操作的通常方法是将nested data type与匹配的nested查询一起使用。

查询最终看起来像这样:

{
  "query": {
    "nested": {
      "path": "labels",
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "fields": ["labels.name"],
                "query": "london",
                "type": "phrase_prefix"
              }
            },
            {
              "term": {
                "labels.lang": "gd"
              }
            }
          ]
        }
      }
    }
  }
}

但是请注意,您还需要为标签指定嵌套映射,例如:

"properties": {
  "labels": {
    "type": "nested",
    "properties": {
      "name": {
        "type": "text"  
        /* you might want to add other mapping-related configuration here */
      },
      "lang": {
        "type": "keyword"
      }
    }
  }
}

其他执行此操作的方法包括:

  • 将每个标签作为单独的文档编制索引,并重复guid字段
  • 使用父/子文档

答案 1 :(得分:0)

您应在映射中使用嵌套数据类型,而不要使用对象数据类型。有关详细说明,请参见:

https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

因此,您应该定义字段映射,如下所示:

 {
  "properties": {
    "labels": {
      "type": "nested",
      "properties": {
        "name": {
          "type": "text"
        },
        "lang": {
          "type": "keyword"
        }
      }
    }
  }
}

此后,您可以使用Nested Query来查询:

{
  "query": {
    "nested": {
      "path": "labels",
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "fields": ["labels.name"],
                "query": "london",
                "type": "phrase_prefix"
              }
            },
            {
              "term": {
                "labels.lang": "gd"
              }
            }
          ]
        }
      }
    }
  }
}