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 支援分詞查詢和精确查詢
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL3MDO3QTOyUTM0AzMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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"
}
}