版本定位:7.x
总结的坑:
- term及terms词条查询时,如果有text及keyword类型,则需加'.keyword'
- queryString全字段搜索时,最好指定字段;并要提前设置好字段mapping:keyword并指定分词器。
- 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方法