ElasticSearch 6.x 小结

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"
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值