ES version:6.8.8,spring-boot-starter-data-elasticsearch:2.1.0.RELEASE,spring-data-elasticsearch:3.1.2.RELEASE,org.elasticsearch.client:6.2.2
1.ES 在建立索引时,text:会进行分词,keyword:不会进行分词,这样在进行查询时,全量查询查keyword字段时可以命中使用分词器查询就无法查询到;全量查询text字段无法命中用分词器查询匹配到则会命中。
2.match和term的区别:term不会分词,match会被分词(.analyzer(“analyzer”))一般模糊查找的时候多用match,而精确查找时可以使用term。
3.term查询keyword字段需要完全匹配才可,term全量匹配text分词的结果才可
4.match分词后需要与keyword全量匹配才可,只要match的分词结果和text的分词结果有匹配即可
5.match_phrase是分词的,text也是分词的。match_phrase的分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。(text:he is a boy,match_phrase:is a 可,is boy 不可,is a girl 不可)
6.query_string是分词的,查询text类型的字段不需要连续,顺序还可以调换。
7.实现 “title”==“a” or (“createrOnly” == true and “createrId” == “b”) or (“projectOnly” == true and “projectId” in [“c”,“d”,“e”])
String[] projectIds = req.getProjectId().split(",");
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
// es计数从0开始
Pageable pageable = PageRequest.of(req.getPageNum() - 1, req.getSize());
builder.withPageable(pageable);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("title", req.getTitle()));
boolQueryBuilder
.should(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("createrOnly", true))
.must(QueryBuilders.termQuery("createrId.keyword", req.getCreaterId())))
.should(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("projectOnly", true))
.must(QueryBuilders.termsQuery("projectId.keyword", projectIds)));
builder.withFilter(boolQueryBuilder);
Page<clazz> page = elasticsearchTemplate.queryForPage(builder.build(), clazz);
JSONObject json = new JSONObject();
json.put("totle", page.getTotalElements());
json.put("pageNum", page.getPageable().getPageNumber() + 1);
json.put("pageSize", page.getPageable().getPageSize());
json.put("items", page.getContent());
8.term做精确查询可以用它来处理数字,布尔值,日期以及文本,当查询字符串且 fields包含text、keyword类型时需要在字段名后拼上**.keyword**这是 es 之 termQuery 精确查询失效问的一个大坑(ES在创建索引时默认 fields类型:参考第9条),否则只能 match 分词查询,最保险的方法是使用kibana查询mapping进行索引查看后再开发。对于多个 must、should 在 sql 中以 [] 包裹多个条件逗号分隔:should:{bool:must[a,b]}
GET myindex/_search
{
"query": {
"bool": {
"must": [
{"match": {
"title": "小猪"
}}
],
"should": [
{
"bool": {
"must": [
{
"term": {
"createrOnly": {
"value": true
}
}
},
{
"term": {
"createrId.keyword": {
"value": "UDP43f1d0787b16447e82d645f9175fd29e"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"projectId": {
"value": true
}
}
},
{
"terms": {
"projectId.keyword": [
"P-2eb738ef48344ef497b60fa5ffae6151",
"P-2eb738ef48344ef497b60fa5ffae6152"
]
}
}
]
}
}
]
}
}
}
9.使用注解 Bean 创建索引无论创建类型 text、keyword,es 默认都会引入 fields 支持分词查询和精确查询
10.创建索引
// createIndex = false 建议关闭启动检测索引,没有则创建的配置
@Document(indexName = "docindex", type = "doctype", createIndex = false)
boolean exist = elasticsearchTemplate.indexExists(clazz);
if(!exist) {
elasticsearchTemplate.createIndex(clazz);
elasticsearchTemplate.putMapping(clazz);
}
// 表示该字段是一个文本,并作最大程度拆分,默认建立索引
@Field(type=FieldType.Text, analyzer="ik_max_word")
// 表示该字段是一个文本,不建立索引
@Field(type=FieldType.Text,index=false)
// 表示该字段是一个文本,日期类型,默认不建立索引
@Field(type=FieldType.Date)
// 表示该字段是一个长整型,默认建立索引
@Field(type=FieldType.Long)
// 表示该字段内容是一个文本并作为一个整体不可分,默认建立索引
@Field(type=FieldType.Keyword)
// 表示该字段内容是一个浮点类型并作为一个整体不可分,默认建立索引
@Field(type=FieldType.Float)
// date 、float、long 都是不能够被拆分的
// 在指定分词索引后,也可以指定查询索引
boolQueryBuilder.must(QueryBuilders.matchQuery("title", req.getTitle()).analyzer("ik_smart"));
11.当索引不在满足于数据查询时,又不想包括数据重头再来时就需要:索引迁移
PUT /new_index
{
// 创建新索引
}
// 迁移
POST _reindex
{
"source": {
"index": "old_index"
},
"dest": {
"index": "new_index"
}
}