0
点赞
收藏
分享

微信扫一扫

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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hcx</groupId>
<artifactId>elasticsearch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>elasticsearch</name>
<description>Demo project for Spring Boot</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

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<Item,Long>{
List<Item> findByTitle(String title);
List<Item> 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<Item> 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> item = itemRepository.findById(1l);
System.out.println(item.get());
}

/**
* 查询多条并排序
*/

@Test
public void testFindAll() {
Iterable<Item> items = itemRepository.findAll(Sort.by("price").descending());
items.forEach(System.out::println);
}

/**
* 根据某个字段查询
*/

@Test
public void testFindByTitle() {
List<Item> items = itemRepository.findByTitle("手机");
items.forEach(System.out::println);
}

@Test
public void testFindByPriceBetween() {
List<Item> items = itemRepository.findByPriceBetween(3099d, 4999d);
items.forEach(System.out::println);
}

/**
* 使用查询构建器查询
*/

@Test
public void testSearch() {
//使用查询构建器工具构建查询条件
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "手机");
Iterable<Item> items = itemRepository.search(queryBuilder);
items.forEach(System.out::println);
}

/**
* 使用自定义查询构建器
*/

@Test
public void testNative() {
//构建自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加基本的查询条件
queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
//执行查询获取分页结果集
Page<Item> 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<Item> 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<Item> 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<Item> itemPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder.build());
//解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
//通过聚合名称brandAgg 获取聚合对象
StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
List<StringTerms.Bucket> 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<Item> itemPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder.build());
//解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
//通过聚合名称brandAgg 获取聚合对象
StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
List<StringTerms.Bucket> buckets = brandAgg.getBuckets();
buckets.forEach(bucket -> {
//聚合名称
System.out.println(bucket.getKeyAsString());
//记录数
System.out.println(bucket.getDocCount());
//子聚合map集合:key:聚合名称 value:子聚合对象
Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();
InternalAvg priceAvg = (InternalAvg) stringAggregationMap.get("price_avg");
System.out.println(priceAvg.getValue());
});
}
}

举报

相关推荐

0 条评论