Elasticsearch学习笔记,看完你就会了
导入依赖
springboot的版本是2.1.9.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置YML文件
spring:
data:
elasticsearch:
cluster-name: my-elasticsearch
cluster-nodes: 192.168.217.128:9300
当你做到这一步,那么算是把环境搭建好了,接下来就是构建索引的实体类
构建索引的实体类
@Data
@Document(indexName = "索引名称", type = "类型", shards = 1, replicas = 0)
public class Goods {
@Id
private Long id;
//analyzer 是使用ik分词器
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String all;
//type = FieldType.Keyword 代表查询的时候不进行分词
//index = false 代表不建立索引
@Field(type = FieldType.Keyword, index = false)
private String skus;
}
创建索引和映射
这里我们使用ElasticsearchTemplate来进行创建索引以及映射,在程序里面直接注入即可
//创建索引 Goods是之前构建的实体类
template.createIndex(Goods.class);
//创建映射 Goods是之前构建的实体类
template.putMapping(Goods.class);
完成之后就是基本的增删改功能了,这我们使用接口继承ElasticsearchRepository的方式,写一个接口直接继承该接口即可
//Goods代表实体类的类型,Long代表该索引的id的类型
public interface GoodsService extends ElasticsearchRepository<Goods,Long> {
}
接口写好之后直接注入即可,调用save方法进行添加,这里要注意修改方法也是save,id相同即可。调用delete方法进行删除或者deleteById进行删除
查询方法
这里直接注入继承了ElasticsearchRepository的接口进行操作
查询所有
1.使用kibbana进行查询
GET 索引名称/_search
{
"query": {
"match_all": {}
}
}
2.使用代码查询
//从es里面查询数据
AggregatedPage<Goods> goods = (AggregatedPage<Goods>)goodsService.findAll();
//得到查询出来得数据集合
List<Goods> content = goods.getContent();
term查询(不会进行分词)
一般用于类型是keyword的字段,查询某某字段等于某某值
1.使用kibbana查询
GET 映射名称/_search
{
"query": {
"term": {
"字段名称": {
"value": "值"
}
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建term查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("字段名称", "值");
//把term查询放入queryBuilder
queryBuilder.withQuery(termQueryBuilder);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//调用注入的接口对象查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
match查询(会进行分词)
会把我们传进去的值进行分词,然后挨个进行查询,默认情况下会把查询的结果求并集
1.使用kibbana查询
GET 映射名称/_search
{
"query": {
"match": {
"字段名称": "值"
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建term查询
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("字段名称", "值");
//把term查询放入queryBuilder
queryBuilder.withQuery(matchQueryBuilder);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
wildcard模糊查询(会进行分词)
使用通配符进行查询
?:任意单个字符
*:0-N个字符
注意:在查询条件最左边使用通配符 效率会很低 慎用
1.使用kibbana查询
GET 映射名称/_search
{
"query": {
"wildcard": {
"字段名称": {
"value": "华为*"
}
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建term查询
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("字段名称", "华为*");
//把term查询放入queryBuilder
queryBuilder.withQuery(wildcardQueryBuilder);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
prefix查询:前缀查询
最好用在keyword上
1.使用kibbana查询
GET 映射名称/_search
{
"query": {
"prefix": {
"字段名称": {
"value": "前缀"
}
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建term查询
PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("字段名称", "前缀");
//把term查询放入queryBuilder
queryBuilder.withQuery(prefixQuery);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
范围与排序查询
range查找指定字段在指定范围内
gte:大于或等于
gt: 大于
lte: 小于或等于
lt: 小于
1.使用kibbana查询
不加分页
GET 映射名称/_search
{
"query": {
"range": {
"字段名称": {
"gte": 1,
"lte": 1000
}
}
}
}
加分页
GET 映射名称/_search
{
"query": {
"range": {
"字段名称": {
"gte": 1,
"lte": 1000
}
}
},
"sort": [
{
"字段名称": {
"order": "desc"
}
}
]
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建range查询
RangeQueryBuilder price = QueryBuilders.rangeQuery("price").gte(1).lte(100);
//把range查询放入queryBuilder
queryBuilder.withQuery(price);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
queryString查询(多字段查询)
使用通配符进行查询
query_string会识别or和and关键字,并且把每个值对每一个fields里面的字段进行分词匹配,查询出来的结果会求并集
1.使用kibbana查询
GET goods_legou_test/_search
{
"query": {
"query_string": {
"fields": ["字段1","字段2"],
"query": "值1 or 值2"
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建term查询
QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("值1 or 值2").field("字段1").field("字段2");
//把term查询放入queryBuilder
queryBuilder.withQuery(queryStringQueryBuilder);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
布尔查询(多个查询条件连接)
must(and):条件必须成立
must_not(not):条件必须不成立
should(or):条件可以成立
filter:条件必须成立,性能比must高。不会计算得分
1.使用kibbana查询
GET 映射名称/_search
{
"query": {
"bool": {
"must": [{}],
"must_not": [{}],
"should": [{}],
"filter": [{}]
}
}
}
GET 映射名称/_search
{
"query": {
"bool": {
"must": [{
"term": {
"字段": {
"value": "值"
}
}
}],
"must_not": [{
"match": {
"字段": "值"
}
}],
"should": [{
"wildcard": {
"字段": {
"value": "值*"
}
}
}],
"filter": [{}]
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建boolQuery查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//设置boolean查询的第一个条件,must必须满足
boolQueryBuilder.must(QueryBuilders.termQuery("字段","值"));
//设置booolean查询的第二个条件,mustNot条件必须不成立
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("字段","值"));
//设置booolean查询的第二个条件,should条件可以成立
boolQueryBuilder.should(QueryBuilders.matchQuery("字段","值"));
//设置booolean查询的第二个条件,filter条件必须成立,性能比must高
boolQueryBuilder.filter(QueryBuilders.matchQuery("字段","值"));
//把term查询放入boolQuery
queryBuilder.withQuery(boolQueryBuilder);
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
聚合查询
这里使用查询全部来展示聚合查询
terms:分组
max:最大值
min:最小值
count:统计数量
1.使用kibbana查询
GET goods_legou_test/_search
{
"query": {
"match_all": {}
},
"aggs": {
"名称": {
"terms": {
"field": "字段"
}
},
"名称2":{
"max": {
"field": "字段2"
}
},
"名称3":{
"min": {
"field": "字段3"
}
},
"名称4":{
"count": {
"field": "字段4"
}
}
}
}
2.使用代码查询
//相当于查询器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//使用QueryBuilders构建matchAllQueryBuilder查询
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
//把term查询放入boolQuery
queryBuilder.withQuery(matchAllQueryBuilder);
//添加聚合查询
queryBuilder.addAggregation(AggregationBuilders.terms("max_price").field("specs.CPU核数.keyword"));
queryBuilder.addAggregation(AggregationBuilders.max("max_price").field("price"));
queryBuilder.addAggregation(AggregationBuilders.min("min_price").field("price"));
queryBuilder.addAggregation(AggregationBuilders.count("总数").field("id"));
//因为会自带分页,所以这里我们手动进行分页
queryBuilder.withPageable(PageRequest.of(0,10000));
//查询并返回结果
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
3.获取查询出来的值
AggregatedPage<Goods> goods = (AggregatedPage<Goods>) goodsService.search(queryBuilder.build());
//获取查询结果的聚合结果,使用的什么聚合查询就把结果转换为什么类型org.elasticsearch.search.aggregations包下面的
//分组查询
Terms max_price = (Terms) goods.getAggregation("名称");
List<? extends Terms.Bucket> buckets = max_price.getBuckets();
for (Terms.Bucket bucket : buckets) {
long l = bucket.getKeyAsNumber().longValue();
}
//最大值
Max max = (Max)goods.getAggregation("名称");
double value = max.getValue();