当前位置:主页 > 查看内容

elasticsearch使用原理

发布时间:2021-04-25 00:00| 位朋友查看

简介:与Lucene和solr中的概念类似。 另外,在SolrCloud中,有一些集群相关的概念,在Elasticsearch也有类似的: 索引集(Indices,index的复数):逻辑上的完整索引分片(shard):数据拆分后的各个部分副本(replica):每个分片的复制 要注意的是:Elasticsearc……

与Lucene和solr中的概念类似。
另外,在SolrCloud中,有一些集群相关的概念,在Elasticsearch也有类似的:

索引集(Indices,index的复数):逻辑上的完整索引分片(shard):数据拆分后的各个部分副本(replica):每个分片的复制

要注意的是:Elasticsearch本身就是分布式的,因此即便你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。

一、创建索引
Elasticsearch采用Rest风格API,因此其API就是一次http请求,你可以用任何工具发起http请求
创建索引的请求格式:

请求方式:PUT请求路径:/索引库名

{

"settings": {
 "number_of_shards": 3,
 "number_of_replicas": 2
 }

}

查看索引设置:
Get请求可以帮我们查看索引信息,格式:
GET /索引库名

二、删除索引
删除索引使用DELETE请求
DELETE /索引库名

三、映射配置
索引库有了,接下来肯定是添加数据。不过数据存储到索引库中,必须指定一些相关属性,在学习Lucene中我们都见到过,包括但不限于以下内容:
字段的数据类型
是否要存储
是否要索引
是否分词
分词器种类
只有配置清楚,Elasticsearch才会帮我们进行索引库的创建(不一定)
1.创建映射字段
PUT /索引库名/_mapping/类型名称
{
"properties": {

"字段名": {
 "type": "类型",
 "index": true,
 "store": true,
 "analyzer": "分词器"
}

}
}
类型名称:就是前面讲的type的概念,类似于数据库中的不同表
字段名:任意填写 ,可以指定许多属性,例如:
type:类型,可以是text、long、short、date、integer、object等
index:是否索引,默认为true
store:是否存储,默认为false
analyzer:分词器,这里的ik_max_word即使用ik分词器
2.查看映射关系
GET /索引库名/_mapping
3.字段属性详解
说几个关键的:
String类型,又分两种:text:可分词,不可参与聚合 keyword:不可分词,数据会作为完整字段进行匹配,可以参与聚合
Numerical:数值类型,分两类:基本数据类型:long、interger、short、byte、double、float、half_float
浮点数的高精度类型:scaled_float 需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。
Date:日期类型。elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。
index影响字段的索引情况。index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引。
boost:激励因子,这个与lucene中一样
4.新增数据
通过POST请求,可以向一个已经存在的索引库中添加数据。
POST /索引库名/类型名
{

"key":"value"

}
5.修改数据
把刚才新增的请求方式改为PUT,就是修改了。不过修改必须指定id

二:查询
我们从4块来讲查询:

基本查询_source过滤结果过滤高级查询排序

1.基本查询
GET /索引库名/_search
{

"query":{
 "查询类型":{
 "查询条件":"查询条件值"
}

}
2、多字段查询(multi_match)
GET /_search
{

"query":{
 "multi_match": {
 "query": "小米",
 "fields": [ "title", "subTitle" ]
}

}
3.词条匹配(term)
GET /_search
{

"query":{
 "term":{
 "price":
}

}

4.多词条精确匹配
GET /_search
{

"query":{
 "terms":{
 "price":[2699.00,2899.00,3899.00]
}

}

三、聚合
image.png
基本概念
image.png
image.png
聚合为桶
image.png
桶内度量
image.png
GET /cars/_search
{

"size" : 0,
"aggs" : { 
 "popular_colors" : { 
 "terms" : { 
 "field" : "color"
 "aggs":{
 "avg_price": { 
 "avg": {
 "field": "price" 
}

}

五、Spring Data Elasticsearch
image.png
Spring Data 是的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率。
image.png
image.png
示例:
@Document(indexName = "item",type = "docs", shards = 1, replicas = 0)
public class Item {

@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //标题
@Field(type = FieldType.Keyword)
private String category;// 分类
@Field(type = FieldType.Keyword)
private String brand; // 品牌
@Field(type = FieldType.Double)
private Double price; // 价格
@Field(index = false, type = FieldType.Keyword)
private String images; // 图片地址

}
image.png
image.png
删除索引:
image.png
自定义查询:
image.png
分页查询:
@Test
public void searchByPage(){

// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本分词查询
queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
// 分页:
int page = 0;
int size = 2;
queryBuilder.withPageable(PageRequest.of(page,size));
// 搜索,获取结果
Page Item items = this.itemRepository.search(queryBuilder.build());
// 总条数
long total = items.getTotalElements();
System.out.println("总条数 = " + total);
// 总页数
System.out.println("总页数 = " + items.getTotalPages());
// 当前页
System.out.println("当前页:" + items.getNumber());
// 每页大小
System.out.println("每页大小:" + items.getSize());
for (Item item : items) {
 System.out.println(item);
}

}

排序:
排序也通用通过NativeSearchQueryBuilder完成:
@Test
public void searchAndSort(){

// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本分词查询
queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
// 排序
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
// 搜索,获取结果
Page Item items = this.itemRepository.search(queryBuilder.build());
// 总条数
long total = items.getTotalElements();
System.out.println("总条数 = " + total);
for (Item item : items) {
 System.out.println(item);
}

}

聚合:
@Test
public void testAgg(){

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 不查询任何结果
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
// 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
queryBuilder.addAggregation(
 AggregationBuilders.terms("brands").field("brand"));
// 2、查询,需要把结果强转为AggregatedPage类型
AggregatedPage Item aggPage = (AggregatedPage Item ) this.itemRepository.search(queryBuilder.build());
// 3、解析
// 3.1、从结果中取出名为brands的那个聚合,
// 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
// 3.2、获取桶
List StringTerms.Bucket buckets = agg.getBuckets();
// 3.3、遍历
for (StringTerms.Bucket bucket : buckets) {
 // 3.4、获取桶中的key,即品牌名称
 System.out.println(bucket.getKeyAsString());
 // 3.5、获取桶中的文档数量
 System.out.println(bucket.getDocCount());

}


本文转自网络,原文链接:https://developer.aliyun.com/article/783776
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐