安裝
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch—5.5.2.tar.gz
tar -vxf elasticsearch-5.5.2.tar.gz
-f 指定文件名
-v 顯示指令執(zhí)行過程
-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 本節(jié)點名
node.master: true 本節(jié)點是master
network.host: 127.0.0.1 ip是這個端口還是9200
./bin/elasticsearch -d
后臺啟動多復制一個從出來
-R, -r, --recursive 復制目錄及目錄內(nèi)的所有項目
cp -r elasticsearch-5.5.2 es_slave1
cp -r elasticsearch-5.5.2 es_slave2
基本概念
- 索引:相當于dataBase 用小寫字母命名 (但是項目中 這個就是表)
- 類型:相當于table (項目中沒這個)
- 文檔:相當于row
- 分片: 每個索引多個分片.每個分片是一個lucene索引,作用是拆分索引,文件變小, 搜索更快 默認分片5
- 備份: 分片的復制, 可以性 分攤搜索壓力 默認備份數(shù)1
分片和索引,只有創(chuàng)建索引時能定 之后不能修改
創(chuàng)建索引
可以看到 0 1 2 3 4 一共5個分片 每個數(shù)字有2個 有一個備份, 3個es 壞掉哪個 數(shù)據(jù)都是完整的
看是否是結構化索引(有沒有結構映射)
還沒有類型 非機構化
這樣以后再去看變成
3分片, 1 備份
name 是 文本類型
country 是 keyword 是一個關鍵詞 不可切分的
查詢
指定數(shù)據(jù)id
macth_all
took 響應耗時4毫秒
hits是響應的全部結果
分頁 只返回一條數(shù)據(jù)
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多個字段上反復執(zhí)行相同查詢
query_string 語法查詢 ,根據(jù)語法規(guī)則的查詢
結構化數(shù)據(jù) 如 數(shù)字 時間
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 距離 現(xiàn)在在10公里之內(nèi)
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;
}