与ElasticSearch完全匹配(在查询时)

时间:2013-08-23 12:08:49

标签: java elasticsearch

我有一个位置索引,它有很多位置名称及其各自的国家/地区。

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

这是我的Java代码尝试:

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

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

(但请注意,我还有其他需要进行子字符串/文本搜索匹配的方案。)

有没有办法决定查询时间,而不是在编制索引时需要哪种行为(精确与分析文本)?

2 个答案:

答案 0 :(得分:10)

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

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

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

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

然后在查询时,如果您希望标题的确切术语“柏林”按照确切的术语“DE”进行过滤,请使用带有not_analyzed字段的术语查询和术语过滤器:

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

请注意,term filtersterm queries要求not_analyzed字段起作用(即返回完全匹配)。

答案 1 :(得分:0)

对于ElasticSearch上的版本5 +,没有分析的概念,也没有分析索引,它是由类型驱动的!

不推荐使用字符串数据类型,并将其替换为text和keyword,因此,如果您的数据类型为text,则其行为类似于字符串,可以进行分析和标记化。

但是如果将数据类型定义为关键字,则自动对其进行NOT分析,并返回完全完全匹配。

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

您可以使用@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"}
            }
          }
        }
      }
    }
  }