【问题标题】:match query vs term query in matching exact field匹配精确字段中的匹配查询与术语查询
【发布时间】:2021-02-05 19:38:59
【问题描述】:

想象以下架构

  {
    "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_stringmy_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));

这对吗?

【问题讨论】:

    标签: java elasticsearch


    【解决方案1】:

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

    请注意,在最新版本的 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);
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-11
      • 2021-05-03
      • 2017-03-02
      • 1970-01-01
      • 2016-03-07
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多