Elasticsearch是搜索服务器
视频地址:https://www.bilibili.com/video/BV1Sy4y1G7LL/?p=6&spm_id_from=333.880.my_history.page.click&vd_source=fc7fa697b97f292319c5b0cde4755484
下载地址:[https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.0-linux-x86_64.tar.gz
数据库搜索缺点](https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.0-linux-x86_64.tar.gz)
性能低
功能瑞
倒排索引
正向索引
初识倒排索引
优化:倒排索引将value修改为对应诗名或者id
Elasticsearch存储和搜索原理
Elasticsearch概念
Elasticsearch和Mysql的不同点
Elasticsearch下载部署
这里在本机玩,不介绍linux下集群部署
下载后
进入elasticsearch bin目录下
./elasticsearch -d
后台启动
mac电脑操作查看进程
jps
查看进程端口
sudo lsof -nP -p 进程号| grep LISTEN
linux查看端口
jps
netstat -nltp
|grep elasticsearch`
默认配置为9200端口为http请求
9300断后为tcp elasticsearch内部通信
访问9200成功即为elasticsearch启动成功
Elasticsearch核心概念
索引,映射,文档
脚本操作ES
基于RESTful风格
操作索引
1.查看es安装成功
GET http://127.0.0.1:9200
2.添加索引
PUT http://127.0.0.1:9200/goods
3.查看指定索引信息及所有索引
GET http://127.0.0.1:9200/goods
GET http://127.0.0.1:9200/_all
4.删除指定索引
DELETE http://127.0.0.1:9200/goods2
5.关闭索引
POST http://127.0.0.1:9200/goods/_close
6.开启索引
POST http://127.0.0.1:9200/goods/_open
操作映射
简单数据类型
字符串:
数值:
布尔
二进制
范围类型
日期
复杂数据类型
数组
对象
添加映射
PUT http://127.0.0.1:9200/person/_mapping
{
"properties":{
"name":{
"type":"keyword"
},
"age":{
"type":"integer"
}
}
}
查询映射
GET http://127.0.0.1:9200/person/_mapping
添加索引的同时添加映射
PUT http://127.0.0.1:9200/person
{
"mappings":{
"properties":{
"name":{
"type":"keyword"
},
"age":{
"type":"integer"
}
}
}
}
添加字段
PUT http://127.0.0.1:9200/person/_mapping
{
"properties":{
"address":{
"type":"text"
}
}
}
操作文档
添加文档
添加文档指定文档id
PUT http://127.0.0.1:9200/person/_doc/1
{
"name":"张三",
"age":20,
"address":"北京"
}
添加文档不指定文档id
POST http://127.0.0.1:9200/person/_doc/
{
"name":"李四",
"age":18,
"address":"朝阳"
}
查询文档
根据id查询文档
GET http://127.0.0.1:9200/person/_doc/8uh0bYgBAYb4xsq8VhGD
查询索引下的所有文档
PUT http://127.0.0.1:9200/person/_doc/_search
修改文档
PUT http://127.0.0.1:9200/person/_doc/1
{
"name":"张飞",
"age":20,
"address":"北京"
}
删除文档
根据id删除文档
DELETE http://127.0.0.1:9200/person/_doc/1
分词器
es内置分词器对中文很不友好
测试
GET http://127.0.0.1:9200/_analyze
{
"analyzer":"standard",
"text":"我爱北京天安门"
}
下载ik分词器
ik分词器和es适配版本
这里用的es为7.17.10所以ik分词器下载地址为
https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.17.1
下载完后放入es的plugin目录下
将解压的elasticsearch-analysis-ik-7.17.1下的文件cp到plugin/analysis-ik下
cp -r /Users/hejiawang/elasticsearch-7.17.10/plugins/analysis-ik/elasticsearch-analysis-ik-7.17.1/* /Users/hejiawang/elasticsearch-7.17.10/plugins/analysis-ik
将ik分词器下的config文件copy到es的config目录下
cp -r /Users/hejiawang/elasticsearch-7.17.10/plugins/analysis-ik/elasticsearch-analysis-ik-7.17.1/config/* /Users/hejiawang/elasticsearch-7.17.10/config
重启es
启动es报错
vi /Users/hejiawang/elasticsearch-7.17.10/plugins/analysis-ik/plugin-descriptor.properties
将elasticsearch.version=7.17.1 改为elasticsearch.version=7.17.10
再次重启
使用ik分词器
ik_smart粗力度分词
GET http://127.0.0.1:9200/_analyze
{
"analyzer":"ik_smart",
"text":"我爱北京天安门"
}
ik_smart细力度分词
GET http://127.0.0.1:9200/_analyze
{
"analyzer":"ik_max_word",
"text":"我爱北京天安门"
}
查询文档
词条查询
词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时才匹配搜索
全文查询
全文查询会分析查询条件,先将查询条件进行分词,然后查询,求并集
Demo演示
指定索引查询所有数据 有一条数据
按词条查询文档
因为查询条件为北京,es默认address使用默认分词器,分词为北,京,朝,阳 无法匹配,除非创建mapping时候指定address映射为ik_max_word即可查到
GET http://127.0.0.1:9200/person/_search
{
"query":{
"term":{
"address":{
"value":"北京"
}
}
}
}
全文查询
GET http://127.0.0.1:9200/person/_search
{
"query":{
"match":{
"address": "北京"
}
}
}
JAVA操作ES
Springboot整合ES
创建Springboot项目
1.引入pom
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.17.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.17.1</version>
</dependency>
2.创建自动装在配置类
package com.hejiawang.elasticsearch.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchConfig {
private String host;
private int port;
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(new HttpHost(host,port,"http")));
}
}
3.创建application.yml并且加上配置
elasticsearch:
host: 127.0.0.1
port: 9200
4.创建测试类
package com.hejiawang.elasticsearch;
import com.hejiawang.elasticsearch.config.ElasticsearchConfig;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ElasticsearchApplicationTests {
@Autowired
RestHighLevelClient client;
@Test
void contextLoads() {
// 1.创建es客户端对象
// RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200,"http")));
System.out.println(client);
}
}
javaAPI操作ES
添加索引
添加索引不指定mapping
/*添加索引*/
@Test
public void addIndex() throws IOException {
// 1.使用client获取操作索引对象
IndicesClient indices = client.indices();
// 2.具体操作返回值
CreateIndexRequest createRequest = new CreateIndexRequest("test_hejiawang");
CreateIndexResponse response = indices.create(createRequest, RequestOptions.DEFAULT);
// 3.根据返回值判断结果
System.out.println(response.isAcknowledged());
}
添加索引指定mapping
/*添加索引*/
@Test
public void addIndex() throws IOException {
// 1.使用client获取操作索引对象
IndicesClient indices = client.indices();
// 2.具体操作返回值
CreateIndexRequest createRequest = new CreateIndexRequest("test_hejiawang2");
// 2.1设置mapping
String mapping = "{\n" +
" \"properties\":{\n" +
" \"name\":{\n" +
" \"type\":\"keyword\"\n" +
" },\n" +
" \"age\":{\n" +
" \"type\":\"integer\"\n" +
" }\n" +
" }\n" +
"}";
createRequest.mapping(mapping, XContentType.JSON);
CreateIndexResponse response = indices.create(createRequest, RequestOptions.DEFAULT);
// 3.根据返回值判断结果
System.out.println(response.isAcknowledged());
}
查询索引
/*查询索引*/
@Test
public void queryIndex() throws IOException {
// 1.使用client获取操作索引对象
IndicesClient indices = client.indices();
GetIndexRequest getRequest = new GetIndexRequest("test_hejiawang2");
GetIndexResponse response = indices.get(getRequest, RequestOptions.DEFAULT);
// 获取结果
Map<String, MappingMetadata> mappings = response.getMappings();
for (String key : mappings.keySet()){
System.out.println(key+":"+mappings.get(key).getSourceAsMap());
}
}
删除索引
/*删除索引*/
@Test
public void deleteIndex() throws IOException {
// 1.使用client获取操作索引对象
IndicesClient indices = client.indices();
DeleteIndexRequest deleteRequest = new DeleteIndexRequest("test_hejiawang2");
AcknowledgedResponse response = indices.delete(deleteRequest, RequestOptions.DEFAULT);
// 3.根据返回值判断结果
System.out.println(response.isAcknowledged());
}
判断索引是否存在
/*判断索引是否存在*/
@Test
public void existIndex() throws IOException {
// 1.使用client获取操作索引对象
IndicesClient indices = client.indices();
GetIndexRequest request = new GetIndexRequest("test_hejiawang2");
boolean exists = indices.exists(request, RequestOptions.DEFAULT);
// 3.根据返回值判断结果
System.out.println(exists);
}
添加文档
添加文档使用map作为数据
/*添加文档*/
@Test
public void addDoc() throws IOException {
// 1.获取操作文档的对象
Map data = new HashMap<>();
data.put("name","张三");
data.put("age",18);
IndexRequest request = new IndexRequest("test_hejiawang2").id("1").source(data);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
// 2.获取结果
System.out.println(response.getId());
}
添加文档使用对象作为数据
创建Person对象
/*添加文档,使用对象作为数据*/
@Test
public void addDoc2() throws IOException {
// 1.获取操作文档的对象
Person person = new Person();
person.setName("王五");
person.setAge(19);
// 将对象转为Json
String data = JSON.toJSONString(person);
IndexRequest request = new IndexRequest("test_hejiawang2").id("1").source(data,XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
// 2.获取结果
System.out.println(response.getId());
}
修改文档
/*修改文档,如果id存在为添加文档,如果id不存在为修改文档*/
@Test
public void updateDoc() throws IOException {
// 1.获取操作文档的对象
Person person = new Person();
person.setName("王五");
person.setAge(19);
// 将对象转为Json
String data = JSON.toJSONString(person);
IndexRequest request = new IndexRequest("test_hejiawang2").id("1").source(data,XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
// 2.获取结果
System.out.println(response.getId());
}
根据id查询文档
/*根据id查询文档*/
@Test
public void findDocById() throws IOException {
GetRequest request = new GetRequest("test_hejiawang2","1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 2.获取结果
System.out.println(response.getSourceAsString());
}
删除文档
/*根据id删除文档*/
@Test
public void deleteDocById() throws IOException {
DeleteRequest request = new DeleteRequest("test_hejiawang2", "1");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
// 2.获取结果
System.out.println(response.getId());
}
ES高级操作
批量操作
批量操作api调用
批量增删改查
POST http://127.0.0.1:9200/_bulk
postmain中最后一定要有个空行,不然会报错
{"delete":{"_index":"test_hejiawang2","_id":"1"}}
{"create":{"_index":"test_hejiawang2","_id":"2"}}
{"name":"何佳旺","age":18}
{"update":{"_index":"test_hejiawang2","_id":"1"}}
{"doc":{"name":"zzz"}}
批量操作java代码
@Test
public void testBulk() throws IOException {
// 创建bulkrequest对象
BulkRequest request = new BulkRequest();
// 添加操作
// 1.删除1号记录
DeleteRequest deleteRequest = new DeleteRequest("test_hejiawang2","1");
request.add(deleteRequest);
// 2.添加6号记录
Map map = new HashMap<>();
map.put("name","飞哥");
IndexRequest indexRequest = new IndexRequest("test_hejiawang2").id("6").source(map);
request.add(indexRequest);
// 3.修改6号记录
Map map2 = new HashMap();
map2.put("name","肥哥");
UpdateRequest updateRequest = new UpdateRequest("test_hejiawang2","6").doc(map2);
request.add(updateRequest);
// 添加操作
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
RestStatus status = response.status();
System.out.println(status);
}
导入数据
1.mysql创建表
CREATE TABLE goods(
id bigint(20),
title varchar(100),
price decimal(20,2),
stock int(10),
saleNum int(10),
creatTime dateTime,
categoryName varchar(200),
brandName varchar(100),
spec varchar(200)
)
2.es创建索引
PUT http://127.0.0.1:9200/goods
{
"mappings":{
"properties":{
"titles":{
"type": "text",
"analyzer":"ik_smart"
},
"price":{
"type": "double"
},
"createTime":{
"type": "date"
},
"categoryName":{
"type": "keyword"
},
"brandName":{
"type": "keyword"
},
"spec":{
"type": "object"
},
"saleNum":{
"type": "integer"
},
"stock":{
"type": "integer"
}
}
}
}
3.在数据库中准备数据数据
insert into 3309test.goods (`id`, `title`, `price`, `stock`, `saleNum`, `creatTime`, `categoryName`, `brandName`, `spec`) values (1, '华为5G', 2399, null, 38, NOW() , '手机', '华为', '{"机身内存":"16g","网络":"联通2G"}');
insert into 3309test.goods (`id`, `title`, `price`, `stock`, `saleNum`, `creatTime`, `categoryName`, `brandName`, `spec`) values (2, '苹果 1', 2399, null, 38, NOW() , '手机', '苹果', '{"机身内存":"16g","网络":"联通2G"}');
4.引入相关依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
5.准备domain
package com.hejiawang.elasticsearch.domain;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
import java.util.Map;
public class Goods {
private int id;
private String title;
private double price;
private int stock;
private int saleNum;
private Date creatTime;
private String categoryName;
private String brandName;
private Map spec;
@JSONField(serialize = false) //在转换JSON时忽略该字段
private String specStr; //接受数据库的信息"{}"
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
public int getSaleNum() {
return saleNum;
}
public void setSaleNum(int saleNum) {
this.saleNum = saleNum;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public Map getSpec() {
return spec;
}
public void setSpec(Map spec) {
this.spec = spec;
}
public String getSpecStr() {
return specStr;
}
public void setSpecStr(String specStr) {
this.specStr = specStr;
}
@Override
public String toString() {
return "Goods{" +
"id=" + id +
", title='" + title + '\'' +
", price=" + price +
", stock=" + stock +
", saleNum=" + saleNum +
", creatTime=" + creatTime +
", categoryName='" + categoryName + '\'' +
", brandName='" + brandName + '\'' +
", spec=" + spec +
", specStr='" + specStr + '\'' +
'}';
}
}
6.准备mapper及xml
GoodMapper
package com.hejiawang.elasticsearch.mapper;
import com.hejiawang.elasticsearch.domain.Goods;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface GoodsMapper {
/*
* 查询所有
* */
public List<Goods> findAll();
}
GoodMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hejiawang.elasticsearch.mapper.GoodsMapper">
<select id="findAll" resultType="goods">
select id,
title,
price,
stock,
saleNum,
creatTime,
categoryName,
brandName,
spec as specStr
from goods
</select>
</mapper>
7.BulkRequest批量导入数据
/*
* 2.批量导入
* */
@Test
public void importData() throws IOException {
// 1.查询所有数据,mysql
List<Goods> goodsList = goodsMapper.findAll();
// goodsList.forEach(n-> System.out.println(n.toString()));
// 2.导入数据
BulkRequest bulkRequest = new BulkRequest();
// 2.1循环goodsList,创建IndexRequest添加数据
for (Goods goods : goodsList) {
// 2.2设置spec规格信息,Map的数据 specStr{}
goods.setSpec(JSON.parseObject(goods.getSpecStr(),Map.class));
// System.out.println(goods.toString());
// System.out.println(JSON.toJSONString(goods));
IndexRequest indexRequest = new IndexRequest("goods");
indexRequest.id(goods.getId()+"").source(JSON.toJSONString(goods), XContentType.JSON);
bulkRequest.add(indexRequest);
}
BulkResponse response = client.bulk(bulkRequest,RequestOptions.DEFAULT);
}
8.执行导入结果
各种查询
matchAll查询
matchALL脚本查询
GET http://127.0.0.1:9200/goods/_search
默认显示10条数据
{
"query":{
"match_all":{}
}
}
分页需要带上from,size
{
"query":{
"match_all":{}
},
"from":0,
"size":100
}
matchAll javaAPI操作
/*
* 查询所有
* 1.matchAll
* 2.将查询结果分装为Goods对象,封装到list中
* 3.分页,默认为10条
* */
@Test
public void testMatchAll() throws IOException {
// 1.构建查询条件构造器,指定查询索引名称
SearchRequest searchRequest = new SearchRequest("goods");
// 2.创建查询条件构造对象
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加分页信息
sourceBuilder.from(0);
sourceBuilder.size(100);
// 3.指定查询条件
MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); //查询所有文档
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 4.获取命中对象
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
term查询
term脚本查询
GET http://127.0.0.1:9200/goods/_search
{
"query":{
"term":{
"categoryName":{
"value":"手机"
}
}
}
}
termAPI查询
/**
* termQuery:词条查询
*/
@Test
public void testTermQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
TermQueryBuilder queryBuilder = QueryBuilders.termQuery("categoryName","手机"); //term词条查询
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
match查询
match脚本查询
GET http://127.0.0.1:9200/goods/_search
{
"query":{
"match":{
"title":{
"query":"三星",
"operator":"and"
}
}
}
}
match API查询
/**
* termQuery:Match查询
*/
@Test
public void testMatchQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title","三星"); //match词条查询
queryBuilder.operator(Operator.AND); //求并集
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
其他查询
模糊查询脚本
模糊查询API
/**
* wildQuery:模糊查询
*/
@Test
public void testWildcardQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery("title","三*");
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
正则查询脚本
正则查询API
/**
* RegexpQuery:正则查询
*/
@Test
public void testRegexpQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RegexpQueryBuilder queryBuilder = QueryBuilders.regexpQuery("title","\\w+(.)*"); //
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
前缀查询脚本
前缀查询API
/**
* PrefixQuery:前缀查询
*/
@Test
public void testPrefixQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
PrefixQueryBuilder queryBuilder = QueryBuilders.prefixQuery("title","三"); //match词条查询
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
范围查询脚本
范围查询API
/**
* rangeQuery:范围查询
*/
@Test
public void testPrefixQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("price");
queryBuilder.gte(2000);
queryBuilder.lte(3000);
sourceBuilder.query(queryBuilder);
// 排序
sourceBuilder.sort("price", SortOrder.ASC);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
queryString脚本查询
queryString API
/**
* queryString:范围查询
*/
@Test
public void testQueryString() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("三星").field("title").field("brandName").defaultOperator(Operator.OR);
sourceBuilder.query(queryBuilder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
}
布尔查询脚本
聚合查询脚本
聚合查询API
/**
* 聚合查询:桶聚合,分词查询
* 1.查询title包含手机的数据
* 2.查询品牌列表
*/
@Test
public void testAggQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 1.查询title包含三星的数据
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "三星");
sourceBuilder.query(queryBuilder);
// 2.查询品牌列表
/*
* 参数
* 1.自定义的名称,将来用于获取数据
* 2.分组的字段
* */
TermsAggregationBuilder builder = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
sourceBuilder.aggregation(builder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
// 获取聚合结果
Aggregations aggregations = response.getAggregations();
Map<String, Aggregation> aggregationMap = aggregations.asMap();
// System.out.println(aggregationMap);
Terms goodsBrands = (Terms) aggregationMap.get("goods_brands");
List<? extends Terms.Bucket> buckets = goodsBrands.getBuckets();
List brands = new ArrayList();
for (Terms.Bucket bucket: buckets){
Object key = bucket.getKey();
brands.add(key);
}
brands.forEach(System.out::println);
}
高亮查询脚本
高亮查询API
/**
* 高亮查询:
* 1.查询title包含手机的数据
* 高亮字段
* 前缀
* 后缀
* 2.讲高亮了的字段数据替换原有数据
*/
@Test
public void testHighLightQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 1.查询title包含三星的数据
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "苹果");
sourceBuilder.query(queryBuilder);
// 2.设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
// 设置三要素
highlightBuilder.field("title");
highlightBuilder.preTags("<front color='red'>");
highlightBuilder.postTags("</front>");
sourceBuilder.highlighter(highlightBuilder);
// 2.查询品牌列表
/*
* 参数
* 1.自定义的名称,将来用于获取数据
* 2.分组的字段
* */
TermsAggregationBuilder builder = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
sourceBuilder.aggregation(builder);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
SearchHits searchHits = response.getHits();
// 5.获取总记录数
long value = searchHits.getTotalHits().value;
System.out.println("总记录数:"+value);
// 获取Hits数据 数组
List<Goods> goodsList = new ArrayList<>();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit:hits){
// 获取json字符串格式的数据
String sourceAsString = hit.getSourceAsString();
// System.out.println(sourceAsString);
// 转为json对象
Goods goods = JSON.parseObject(sourceAsString, Goods.class);
// 获取高亮结果,替换goods中的title
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlightField = highlightFields.get("title");
Text[] fragments = highlightField.fragments();
// 替换
goods.setTitle(fragments[0].toString());
goodsList.add(goods);
}
goodsList.forEach(System.out::println);
// 获取聚合结果
Aggregations aggregations = response.getAggregations();
Map<String, Aggregation> aggregationMap = aggregations.asMap();
// System.out.println(aggregationMap);
Terms goodsBrands = (Terms) aggregationMap.get("goods_brands");
List<? extends Terms.Bucket> buckets = goodsBrands.getBuckets();
List brands = new ArrayList();
for (Terms.Bucket bucket: buckets){
Object key = bucket.getKey();
brands.add(key);
}
brands.forEach(System.out::println);
}
索引别名和重建索引
重建索引
1.创建V1索引
PUT http://127.0.0.1:9200/student_index_v1
{
"mappings":{
"properties":{
"birthday":{
"type":"date"
}
}
}
}
2.往V1索引中插入数据
PUT http://127.0.0.1:9200/student_index_v1/_doc/1
{
"birthday":"2000-11-21"
}
3.创建V2的索引
PUT http://127.0.0.1:9200/student_index_v2
{
"mappings":{
"properties":{
"birthday":{
"type":"date"
}
}
}
}
4.将V1索引中的数据copy到V2索引中
PUT http://127.0.0.1:9200/_reindex
{
"source":{
"index":"student_index_v1"
},
"dest":{
"index":"student_index_v2"
}
}
对索引取别名
POST http://127.0.0.1:9200/student_index_v2/_alias/student_index_v3