首页 > 解决方案 > 匹配精确字段中的匹配查询与术语查询

问题描述

想象一下以下架构

  {
    "mappings": {
      "my_mappinng": {
        "dynamic": false,
        "_all":       { "enabled": false },
        "_source":    { "enabled": true },
        "properties": {
            "my_string":             { "type": "string",  "store": true, "index" : "not_analyzed" },
            "my_boolean":            { "type": "boolean", "store": true },
            "my_long":               { "type": "long",    "store": true }
        }
      }
    },
    "settings" : {
      "index" : {
          "number_of_shards" : 9,
          "number_of_replicas" : 1
      }
    }
  }'

如果我想要一个与my_string,my_booleanmy_long

是标准推荐

  1. 将字符串字段设置为“not_analyzed”以使其不被标记化
  2. 使用术语查询而不是匹配查询
           BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_string", "string_i_want_to_match");
           query.should(my_filter);

           BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_boolean", true);
           query.should(my_filter);

           BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_long", 1l);
           query.should(my_filter);


而不是

       BoolQueryBuilder query = QueryBuilders.boolQuery();
       query.must(matchQuery("my_string", "string_i_want_to_match"));

       BoolQueryBuilder query = QueryBuilders.boolQuery();
       query.must(matchQuery("my_boolean", true));

       BoolQueryBuilder query = QueryBuilders.boolQuery();
       query.must(matchQuery("my_long", 1l));

这个对吗?

标签: javaelasticsearch

解决方案


看起来您使用的是旧版本的 ES,其中不支持关键字数据类型,因此在这种情况下您是正确的,但如果您升级 ES 而不是定义not_analyzed(已弃用),您应该使用keyword顾名思义不支持的数据类型更改并创建与您应该使用的输入和以后的查询text相同的令牌,这用于完全匹配场景。textterm

请注意,在最新版本的 ES 中,如果您没有定义映射,默认情况下每个text字段,一个text用于全文搜索的.keyword字段和一个用于聚合的字段,都会创建排序。

简而言之,您的以下 Java 代码对于您的用例是正确的。

  BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_string", "string_i_want_to_match");
           query.should(my_filter);

           BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_boolean", true);
           query.should(my_filter);

           BoolQueryBuilder query = QueryBuilders.boolQuery();
           QueryBuilder my_filter = QueryBuilders.termQuery("my_long", 1l);
           query.should(my_filter);



推荐阅读