ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Elasticsearch中可避免的坑

2026/9/28 4:21:27 拓冰建站 浏览量
Elasticsearch中可避免的坑

版本定位:7.x

总结的坑:

  1. term及terms词条查询时,如果有text及keyword类型,则需加'.keyword'
  2. queryString全字段搜索时,最好指定字段;并要提前设置好字段mapping:keyword并指定分词器。
  3. reindex做数据迁移时,先创建一个新索引,然后指定源索引与新创建的目标索引,此时会出现502超时。解决方式:
  • 增加分片数slices=9,及wait_for_completion=false异步执行,也可用size指定每批次数量提高效率。
  • 返回任务task:ID。
  • 请求,返回状态信息。GET /_tasks/ID

数据迁移请求:

POST /_reindex?slices=9&refresh&wait_for_completion=false
{"source": {"index": "source_index","size": 1000},"dest": {"index": "target_index"}
}

4. ik分词器版本问题:如果没有elasticseach对应的版本的ik,可以下载相近版本ik,并把ik里的properties文件的elaticsearch.version改成应用版本即可。

5. 时间格式转换,如果把原来的text-keword类型直接更改为date类型,那么原有的时间格式的数据转换失败,需在更换为date类型时,并指定时间格式:"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"。
6.得分排序时,必需要匹配查询,优先使用自定义得分搜索排序
7.为空时给个设定的默认值,以便布尔查询过滤的时候可以查出:示例:

PUT /es_test
{"mappings": {"properties": {"tags": {"type": "keyword","null_value": "null"  // 为空时,默认为"null",显示为null。用布尔过滤的单词条可以查出},"brand_id": {"type": "keyword"    // 没有加空值默认值时,显示依然为null。但是不能查出。}}}
}


8.默认查询前一万条数据,如果分页导致查询一万条之后的数据,需要设置

PUT /es_test/_settings
{"index":{"max_result_window":10000000}
}


9.聚合去重

GET /es_test/_search
{"track_total_hits": true, "query": {"match_all": {}},"collapse": {"field": "product_id"},"aggs": {"search_total": {"cardinality": {"field": "product_id"}}}
}// 对应Java代码            
// 折叠去重“product_id”
CollapseBuilder collapseBuilder = new CollapseBuilder(SearchConstants.QUERY_PRODUCT_INFO_BOOL_QUERY_COLUMN.PRODUCT_ID);
// 聚合去重计算总数,这里聚合存在误差,设置精确度最大
AggregationBuilder cardinalityAggregationBuilder = AggregationBuilders.cardinality(SearchConstants.AGG_CONSTRANTS.CARDINALITY_NAME).field(SearchConstants.QUERY_PRODUCT_INFO_BOOL_QUERY_COLUMN.PRODUCT_ID).precisionThreshold(40000L);

其中返回值:

  • hits中total的总条数实际上是去重前的总条数,原数据条数,这里我们知道就行,分页中我们并不使用它。hits中数组的大小刚好等于courseAgg聚合的值,数组中的数据就是去重后的数据。
  • aggregations中的courseAgg条数,这个才是去重后的实际条数,也是分页用的总条数。

10.分词匹配时,特殊英文符号解析时会报错,要对字符串转义过滤后再搜索。转义方法:
public static String escape(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
                    || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
                    || c == '*' || c == '?' || c == '|' || c == '&' || c == '/') {
                sb.append('\\');
            }
            sb.append(c);
        }
        return sb.toString();
    }
或者直接用escape方法

最后还附上官网地址:Elasticsearch Guide [8.12] | Elastic