9

我有一个位置索引,其中包含许多位置名称及其各自的国家/地区。

然后我想知道我们在国家代码“DE”的国家是否有标题为“Berlin”的地点。

这是我的 Java 代码尝试:

SearchResponse response = client.prepareSearch("locations")
                .setQuery(QueryBuilders.matchQuery("title", "Berlin"))
                .setFilter(FilterBuilders.termFilter("country", "DE"))
                .execute()
                .actionGet();

但这给了我太多的回复,例如“柏林动物园”的结果等等。我需要完全匹配。

(但请注意,我还有其他需要这种子字符串/文本搜索匹配的场景。)

有没有办法在查询时而不是在索引时决定人们想要哪种行为(精确与分析的文本)?

4

2 回答 2

10

将您执行术语过滤的字段索引为 not_analyzed。例如,您可以将“国家”字段索引为 multi_field,其中一个子字段 not_analyzed:

        "country": {
            "type": "multi_field",
            "fields": {
                "country": {"type": "string", "index": "analyzed"},
                "exact": {"type": "string","index": "not_analyzed"}
            }
        }

此外,您可以对“title”字段执行相同的操作以执行术语查询:

        "title": {
            "type": "multi_field",
            "fields": {
                "title": {"type": "string", "index": "analyzed"},
                "exact": {"type": "string","index": "not_analyzed"}
            }
        }

然后在查询时,如果您想要一个带有精确术语“Berlin”的标题,并由精确术语“DE”过滤,请使用带有 not_analyzed 字段的术语查询和术语过滤器:

SearchResponse response = client.prepareSearch("locations")
                .setQuery(QueryBuilders.termQuery("title.exact", "Berlin"))
                .setFilter(FilterBuilders.termFilter("country.exact", "DE"))
                .execute()
                .actionGet();

请注意,术语过滤器术语查询需要 not_analyzed 字段才能工作(即返回完全匹配)。

于 2013-08-23T14:24:15.043 回答
1

在 ElasticSearch 上的版本 5 + 中没有已分析和未分析索引的概念,它由类型驱动!

不推荐使用字符串数据类型并用文本和关键字替换,因此如果您的数据类型是文本,它将表现得像字符串并且可以被分析和标记化。

但是如果数据类型被定义为关键字,那么它会自动不被分析,并返回完全精确匹配。

因此,当您想要进行完全匹配时,您应该记住将类型标记为关键字。

并且您可以使用@Scott Rice 解释的相同术语查询和术语过滤器。

下面的代码示例用于使用此定义创建索引,请注意,我为每个字段创建了两种类型,一种是可标记的,所以类型是文本,另一种是精确的,所以类型是关键字,有时对于某些字段同时保留这两种类型很有用:

PUT testindex
{
    "mappings": {
      "original": {
        "properties": {
          "@timestamp": {
            "type": "date"
          },
          "@version": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "APPLICATION": {
            "type": "text",
            "fields": {
                "token": {"type": "text"},
                "exact": {"type": "keyword"}
            }
          },
          "type": {
            "type": "text",
            "fields": {
                "token": {"type": "text"},
                "exact": {"type": "keyword"}
            }
          }
        }
      }
    }
  }
于 2017-09-12T19:28:51.127 回答