安装
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch—5.5.2.tar.gz
tar -vxf elasticsearch-5.5.2.tar.gz
-f 指定文件名
-v 显示指令执行过程
-x 解压
解压后里面有
LICENSE.txt
README.tex
tile
config 配置
modules 模块
NOTICE.txt
bin 启动脚本
lib 依赖的第三方库
plugins 第三方插件
启动
./bin/elasticsearch
看到started 输出 就是启动好了 -d 后台启动
输出{127.0.0.1:9200} es默认端口是9200
head插件
https://github.com/mobz/elasticsearch-head
wget https://github.com/mobz/elasticsearch-head/archive/master.zip
解压unzip master.zip
es改配置 vim config/elasticsearch.yml
此时再去看 就是好看的界面了 不是直接给json 了
在最后加上
http.cors.enabled: true
http.cors.allow-origin: "*"
ESC :wq
./bin/elasticsearch -d
后台启动
这时候再去就能看到可视化界面了
分布式安装
es改配置 vim config/elasticsearch.yml
最后加上
cluster.name: wali 集群名
node.name: master 本节点名
node.master: true 本节点是master
network.host: 127.0.0.1 ip是这个端口还是9200
./bin/elasticsearch -d
后台启动多复制一个从出来
-R, -r, --recursive 复制目录及目录内的所有项目
cp -r elasticsearch-5.5.2 es_slave1
cp -r elasticsearch-5.5.2 es_slave2
基本概念
- 索引:相当于dataBase 用小写字母命名 (但是项目中 这个就是表)
- 类型:相当于table (项目中没这个)
- 文档:相当于row
- 分片: 每个索引多个分片.每个分片是一个lucene索引,作用是拆分索引,文件变小, 搜索更快 默认分片5
- 备份: 分片的复制, 可以性 分摊搜索压力 默认备份数1
分片和索引,只有创建索引时能定 之后不能修改
创建索引
可以看到 0 1 2 3 4 一共5个分片 每个数字有2个 有一个备份, 3个es 坏掉哪个 数据都是完整的
看是否是结构化索引(有没有结构映射)
还没有类型 非机构化
这样以后再去看变成
3分片, 1 备份
name 是 文本类型
country 是 keyword 是一个关键词 不可切分的
查询
指定数据id
macth_all
took 响应耗时4毫秒
hits是响应的全部结果
分页 只返回一条数据
match 标题字段包括某词的(查询词拆分)
match_phrase 习语匹配 词不被拆分
aggs field 聚合查询
"group_by_word_count" 是随便取的一个名字,
按"word_count"这个字段聚合,这个字段类型是integer
"group_by_word_count"这种并列的可以再来几个,可以结果会有几组聚合
aggs stats stats换成 min 就只返回一项min
高级查询
match_phrase
multi_match多个字段上反复执行相同查询
query_string 语法查询 ,根据语法规则的查询
结构化数据 如 数字 时间
Filter context
es会对结果进行缓存 ,更快
复合查询
spring boot 中使用
筛选+ order
@Inject private ElasticsearchTemplate elasticsearchTemplate;
@Override
public Page<IntelligentStoreDTO> findAll(IntelligentStoreQueryRequest request) {
//各种筛选条件
BoolQueryBuilder qb = QueryBuilders.boolQuery();
qb.must(QueryBuilders.matchQuery("name", request.getName()));
qb.must(QueryBuilders.termQuery("area.provinceId", request.getAreaId()));
LocalDateTime dateTime = LocalDateTime.parse(" 2018-12-11 00:00:00";DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
qb.must(QueryBuilders.rangeQuery("createTime").gt(dateTime));
//排序
Sort.Order createTimeDesc = new Sort.Order(Sort.Direction.DESC, "createTime");
Sort sort = new Sort(createTimeDesc);
Pageable pageable=new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
NativeSearchQueryBuilder nativeSearchQueryBuilder =
new NativeSearchQueryBuilder() .withQuery(qb) .withPageable(pageable);
//location 距离 现在在10公里之内
GeoDistanceQueryBuilder builder =
QueryBuilders.geoDistanceQuery("location")
.point(request.getLat(),request.getLon())
.distance(10000D, DistanceUnit.METERS)
.geoDistance(GeoDistance.ARC);
GeoDistanceSortBuilder sortBuilder =
SortBuilders.geoDistanceSort("location")
.point(request.getLat(),request.getLon())
.unit(DistanceUnit.METERS)
.order(SortOrder.ASC);
nativeSearchQueryBuilder.withFilter(builder).withSort(sortBuilder);
//返回IntelligentStoreDTO 类型的查询结果
return elasticsearchTemplate.queryForPage(
nativeSearchQueryBuilder.build(), IntelligentStoreDTO.class);
}
聚合 总销量
/** 订单总销售额 */
private double countOrderPrice(EEmployeeDTO eEmployeeDTO) {
BoolQueryBuilder filter =
QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("enterpriseId", eEmployeeDTO.getEnterpriseId()));
SearchQuery searchQuery =
new NativeSearchQueryBuilder()
.withQuery(filter)
.withSearchType(SearchType.DEFAULT)
.withIndices("v_enterprise_order_query")
.withTypes("eorderdto")
.addAggregation(AggregationBuilders.sum("total").field("totalAmount"))
.build();
Aggregations aggregations =
(Aggregations) elasticsearchTemplate.query(
searchQuery, (ResultsExtractor) searchResponse -> searchResponse.getAggregations());
List<Aggregation> list = aggregations.asList();
InternalSum aggregation = (InternalSum) list.get(0);
return aggregation.getValue();
}
按日期聚合销量
private List<EDayOrderNumVo> countByDate(
String enterpriseId, String storeId, LocalDateTime start, LocalDateTime end) {
// 限制
BoolQueryBuilder filter = getBoolQueryBuilder(enterpriseId, storeId, end, start);
SearchRequestBuilder searchRequestBuilder =
elasticsearchTemplate.getClient().prepareSearch("v_enterprise_order_query").setTypes("eorderdto").setQuery(filter);
//按createTime 分组count销量
DateHistogramBuilder field = AggregationBuilders.dateHistogram("orderNum").field("createTime");
field.interval(DateHistogramInterval.DAY);
field.format("yyyy-MM-dd");
field.minDocCount(0);
searchRequestBuilder.addAggregation(field);
searchRequestBuilder.setSize(0);
// 查询
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
Histogram sales = searchResponse.getAggregations().get("orderNum");
List<EDayOrderNumVo> vos =
sales
.getBuckets()
.stream()
.map(
e -> {
EDayOrderNumVo vo = new EDayOrderNumVo();
vo.setDate(e.getKeyAsString());//日期
vo.setOrderNum(e.getDocCount());//销量
return vo;
})
.collect(Collectors.toList());
return vos;
}
得销量前几名的店
@NotNull
private List<EStoreOrderRankVo> aggStoreOrderRankVos(Integer rankSize, BoolQueryBuilder filter) {
TermsBuilder termsBuilder =
AggregationBuilders.terms("rank")//随便取一个名字
.field("storeId")//按店id聚合
.order(Terms.Order.count(false))//false:倒序
.size(rankSize);//前rankSize名
SearchQuery searchQuery =
new NativeSearchQueryBuilder()
.withQuery(filter)
.withSearchType(SearchType.DEFAULT)
.withIndices('v_enterprise_order_query')//索引
.withTypes('eorderdto')//类型
.addAggregation(termsBuilder)
.build();
StringTerms agg =
elasticsearchTemplate.query(
searchQuery,
resp -> {
Aggregations aggs = resp.getAggregations();
return aggs.get("rank");//刚才自己取的名字
});
List<EStoreOrderRankVo> collect =
agg.getBuckets()
.stream()
.map(
term -> {
EStoreOrderRankVo vo = new EStoreOrderRankVo();
vo.setStoreId(term.getKeyAsString());
vo.setOrderNum(term.getDocCount());
return vo;
})
.collect(Collectors.toList());
return collect;
}