Elasticsearch初识
一、安装和配置
1.安装
elasticsearch默认不允许以root账号运行,所以创建一个用户
创建用户:useradd tracy
设置密码:passwd xxx
此时可能由于密码过于简单提示,直接再输入一次回车即可
切换用户:su - tracy
上传安装包
切回root用户,分配tracy用户权限:
chown tracy:tracy elasticsearch-6.3.0.tar.gz
chmod 755 elasticsearch-6.3.0.tar.gz
解压之后的目录:
2.配置
如果服务器内存不够,修改config目录下的jvm.options文件:
指定索引库和日志文件、设置允许所有ip访问(默认不允许远程服务器访问):
建立对应的文件夹
3.启动
启动中出现以下两个错误:
解决:
线程数不够
修改文件 vim /etc/security/limits.d/90-nproc.conf
* soft nproc 1024
--->* soft nproc 4096
文件权限不足
切换回root用户,修改文件/etc/security/limits.conf
添加内容:
soft nofile 65536
hard nofile 131072
soft nproc 4096
hard nproc 4096
进程虚拟内存
vm.max_map_count:限制一个进程可以拥有的VMA(虚拟内存区域)的数量,继续修改配置文件:
vim /etc/sysctl.conf
添加内容:vm.max_map_count=655360
执行命令:sysctl -p
安装分词器到elasticsearch/plugins目录下
unzip elasticsearch-analysis-ik-6.3.0.zip -d ik-analyzer
二、客户端
Low Level Rest Client是低级别封装,提供一些基础功能,但更灵活
High Level Rest Client,是在Low Level Rest Client基础上进行的高级别封装,功能更丰富和完善,而且API会变的简单
三、Spring Data Elasticsearch
application.yml
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 120.111.61.110:9300
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.6.RELEASE
com.hcx
elasticsearch
0.0.1-SNAPSHOT
elasticsearch
Demo project for Spring Boot
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-data-elasticsearch
org.springframework.boot
spring-boot-starter
org.projectlombok
lombok
1.18.6
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
Item:
package com.hcx.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* Created by hongcaixia on 2020/2/27.
*/
@Data
@Document(indexName = "item",type = "docs",shards = 1,replicas = 0)
@NoArgsConstructor
@AllArgsConstructor
public class Item {
@Id
Long id;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
String title; //标题
@Field(type = FieldType.Keyword)
String category;// 分类
@Field(type = FieldType.Keyword)
String brand; // 品牌
@Field(type = FieldType.Double)
Double price; // 价格
@Field(type = FieldType.Keyword,index = false)
String images; // 图片地址
}
ItemRepository:
package com.hcx.repository;
import com.hcx.pojo.Item;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
/**
* Created by hongcaixia on 2020/2/28.
*/
public interface ItemRepository extends ElasticsearchRepository- {
List
- findByTitle(String title);
List
- findByPriceBetween(Double d1,Double d2);
}
ElasticsearchTest:
package com.hcx.elasticsearch;
import com.hcx.pojo.Item;
import com.hcx.repository.ItemRepository;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.*;
/**
* Created by hongcaixia on 2020/2/27.
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class ElasticsearchTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private ItemRepository itemRepository;
@Test
public void testIndex() {
elasticsearchTemplate.createIndex(Item.class);
elasticsearchTemplate.putMapping(Item.class);
}
/**
* 新增/更新
*/
@Test
public void testCreate() {
Item item = new Item(1L, "小米10", "手机", "小米", 3999.00,
"http:/image.myshoppingmall.com/1.jpg");
itemRepository.save(item);
}
/**
* 批量新增
*/
@Test
public void indexList() {
List- list = new ArrayList<>();
list.add(new Item(2L, "坚果pro2", " 手机", "锤子", 3099.00, "http://image.myshoppingmall.com/2.jpg"));
list.add(new Item(3L, "华为META20", " 手机", "华为", 4399.00, "http://image.myshoppingmall.com/3.jpg"));
// 接收对象集合,实现批量新增
itemRepository.saveAll(list);
}
/**
* 删除
*/
@Test
public void testDelete() {
Item item = new Item(1L, "小米10", "手机", "小米", 3999.00,
"http:/image.myshoppingmall.com/1.jpg");
itemRepository.delete(item);
}
/**
* 根据id查找单条
*/
@Test
public void testFind() {
Optional
- item = itemRepository.findById(1l);
System.out.println(item.get());
}
/**
* 查询多条并排序
*/
@Test
public void testFindAll() {
Iterable
- items = itemRepository.findAll(Sort.by("price").descending());
items.forEach(System.out::println);
}
/**
* 根据某个字段查询
*/
@Test
public void testFindByTitle() {
List
- items = itemRepository.findByTitle("手机");
items.forEach(System.out::println);
}
@Test
public void testFindByPriceBetween() {
List
- items = itemRepository.findByPriceBetween(3099d, 4999d);
items.forEach(System.out::println);
}
/**
* 使用查询构建器查询
*/
@Test
public void testSearch() {
//使用查询构建器工具构建查询条件
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "手机");
Iterable
- items = itemRepository.search(queryBuilder);
items.forEach(System.out::println);
}
/**
* 使用自定义查询构建器
*/
@Test
public void testNative() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加基本的查询条件
queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
//执行查询获取分页结果集
Page
- itemPage = itemRepository.search(queryBuilder.build());
System.out.println(itemPage.getTotalPages());
System.out.println(itemPage.getTotalElements());
itemPage.getContent().forEach(System.out::println);
}
/**
* 分页
*/
@Test
public void testPage() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加基本的查询条件
queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
//添加分页条件,页码从零开始
queryBuilder.withPageable(PageRequest.of(0, 2));
//执行查询获取分页结果集
Page
- itemPage = itemRepository.search(queryBuilder.build());
System.out.println(itemPage.getTotalPages());
System.out.println(itemPage.getTotalElements());
itemPage.getContent().forEach(System.out::println);
}
/**
* 排序
*/
@Test
public void testSort() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加基本的查询条件
queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
//根据价格降序
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
//执行查询获取分页结果集
Page
- itemPage = itemRepository.search(queryBuilder.build());
System.out.println(itemPage.getTotalPages());
System.out.println(itemPage.getTotalElements());
itemPage.getContent().forEach(System.out::println);
}
@Test
public void testAggregation() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加聚合
queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand"));
//添加结果集过滤,不包含任何字段
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
//执行聚合查询
AggregatedPage
- itemPage = (AggregatedPage
- ) itemRepository.search(queryBuilder.build());
//解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
//通过聚合名称brandAgg 获取聚合对象
StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
List
buckets = brandAgg.getBuckets();
buckets.forEach(bucket -> {
//聚合名称
System.out.println(bucket.getKeyAsString());
//记录数
System.out.println(bucket.getDocCount());
});
}
@Test
public void testSubAggregation() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加聚合
queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand")
.subAggregation(AggregationBuilders.avg("price_avg").field("price")));
//添加结果集过滤,不包含任何字段
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
//执行聚合查询
AggregatedPage- itemPage = (AggregatedPage
- ) itemRepository.search(queryBuilder.build());
//解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
//通过聚合名称brandAgg 获取聚合对象
StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
List
buckets = brandAgg.getBuckets();
buckets.forEach(bucket -> {
//聚合名称
System.out.println(bucket.getKeyAsString());
//记录数
System.out.println(bucket.getDocCount());
//子聚合map集合:key:聚合名称 value:子聚合对象
Map stringAggregationMap = bucket.getAggregations().asMap();
InternalAvg priceAvg = (InternalAvg) stringAggregationMap.get("price_avg");
System.out.println(priceAvg.getValue());
});
}
}
共有 0 条评论