ElasticSearch使用总结

ElasticSearch是什么
Lucene是单机的模式,如果你的数据量超过了一台物理机的容量,你需要扩容,将数据拆分成2份放在不同的集群,这个就是典型的分布式计算了。需要拷贝容错,机器宕机,数据一致性等复杂的场景,这个实现就比较复杂了。
ES解决了这些问题
1、自动维护数据的分布到多个节点的索引的建立,还有搜索请求分布到多个节点的执行
2、自动维护数据的冗余副本,保证了一旦机器宕机,不会丢失数据
3、封装了更多高级的功能,例如聚合分析的功能,基于地理位置的搜索
es使用场景
维基百科
The Guardian(国外新闻网站)
Stack Overflow(国外的程序异常讨论论坛)
GitHub(开源代码管理)
电商网站
日志数据分析
商品价格监控网站
BI系统
站内搜索
ElasticSearch的特点
可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起
对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES
Elasticsearch作为传统数据库的一个补充,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;
分组查询
聚合查询
聚合提供了用户进行分组和数理统计的能力,可以把聚合理解成SQL中的GROUP BY和分组函数
指标聚合/桶聚合
Metrics(度量/指标):简单的对过滤出来的数据集进行avg,max操作,是一个单一的数值
Bucket(桶):将过滤出来的数据集按条件分成多个小数据集,然后Metrics会分别作用在这些小数据集上
高亮查询
//高亮显示查询结果
@Test
public void demo9() throws Exception{
//创建连接搜索服务器的对象
Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(“127.0.0.1”),9300));
ObjectMapper objectMapper = new ObjectMapper();
//搜索 数据
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(“blog2”).setTypes(“article”).setQuery(QueryBuilders.termQuery(“title”,“搜索 “));
//高亮定义
searchRequestBuilder.addHighlightedField(“title”);//对title字段进行高亮显示
searchRequestBuilder.setHighlighterPreTags(””);//前置元素
searchRequestBuilder.setHighlighterPostTags("
");//后置元素
SearchResponse searchResponse = searchRequestBuilder.get();
SearchHits hits = searchResponse.getHits();//获取命中次数,查询结果有多少对象
System.out.println(“查询结果有:”+hits.getTotalHits()+“条”);
Iterator iterator = hits.iterator();
while(iterator.hasNext()){
SearchHit searchHit = iterator.next();//每个查询对象
//将高亮处理后的内容,替换原有内容(原有内容,可能会出现显示不全)
Map<String,HighlightField> hightlightFields = searchHit.getHighlightFields();
HighlightField titleField = hightlightFields.get(“title”);
//获取到原有内容中 每个高亮显示 集中位置fragment就是高亮片段
Text[] fragments = titleField.fragments();
String title = “”;
for(Text text:fragments){
title += text;
}
//将查询结果转换为对象
Article article = objectMapper.readValue(searchHit.getSourceAsString(),Article.class);
//用高亮后的内容,替换原有内容
article.setTitle(title);
System.out.println(article);
}
//关闭连接
client.close();
}

Elasticsearch【ES】第一天
(1) ES是什么? 全文检索?
(2)数据的查询,都是从数据库中查询,为什么还要多一个全文检索。
数据库查询有什么问题?
(3)ES的相关概
索引库、文档、映射、域
(4)如何使用ES
》ES的安装
》如何和ES进行数据交互
》如何通过Java代码操作ES
数据库查询有什么问题
数据库模糊查询,前百分号会导致索引失效,数据量够大的话,查询效率非常低。
不三不四
不三不四--------------->页码
不三不%
%三不四
1000000条数据,平均查询到一条记录的搜索次数?
1000000/2 = 500000
功能弱
%帅哥美女%
倒排索引(重点)
在这里插入图片描述
全文检索的过程分析
在这里插入图片描述
Lucene: java开发的开源的一个优秀的搜索【引擎】工具包。
Lucene不能独立实现全文检索。
Lucene
solr
elasticsearch
全文检索和关系型数据库
全文检索:数据的搜索
关系型数据库:数据的维护。
Elasticsearch的安装
原有镜像需要调整的地方,要更改JDK的版本
vim /etc/profile

把JDK1.8路径改成elasticsearch-7.4.0自带JDK的路径

source /etc/profile

验证: java -version

在这里插入图片描述
Restful风格
同一个url根据请求方式的不一样,来做不同的操作。
GET 查询
POST 新增/修改
PUT 修改
DELETE 删除
POSTMAN进行索引的操作
新增
删除
查询
关闭
打开
映射作用
指定文档需要存储哪些字段(Field域),设置域的相关属性。
创建索引的时候添加映射
mapping的json格式是什么?
已经存在索引
{
“properties”:{
“name”:{
“type”:“keyword”
},
“address”:{
“type”:“text”
}
}
}

为已经存在的索引添加映射
不存在索引
{
“mappings”: {
“properties”: {
“id”:{
“type”:“long”
},
“title”:{
“type”:“keyword”
},
“description”:{
“type”:“text”
}
}
}
}

类型
long short dobule boolean date
字符串类型:text/keyword
keyword不会分词
text:会分词

映射的创建
映射的查询
映射字段的添加
kibana命令

#1.添加索引库
PUT blog
​
#2.删除索引库
DELETE blog
​
#3.为索引库添加映射
PUT blog/_mapping
{
"properties":{
"id":{
"type":"long"
},
"title":{
"type":"keyword"
},
"description":{
"type":"text"
}
}
}
#4.创建索引库的时候添加映射
PUT blog
{
"mappings": {
  "properties": {
    "id":{
      "type":"long"
    },
    "title":{
      "type":"keyword"
    },
    "description":{
      "type":"text"
    }
  }
}
}#5.查询映射
GET /blog/_mapping
​
#6.添加文档 指定主键ID
PUT blog/_doc/1
{
"id":1,
"title":"SpringBoot从入门到精通",
"description":"SpringBoot是一个用来快速构建Spring开发环境的框架"
}
#7.根据ID查询文档
GET blog/_doc/1
​
#8.添加文档 不指定主键ID
POST blog/_doc
{
"id":1,
"title":"SpringCloud从入门到精通",
"description":"SpringCloud是用来治理微服务,是很多组件的集合"
}#9.查询所有记录
GET blog/_search
​
#10.条件查询
GET blog/_search
{
"query":{
  "term": {
    "title": {
      "value": "SpringBoot从入门到精通"
    }
  }
}
}
​
GET blog/_search
{
"query": {
  "term": {
    "description": {
      "value": "用来"
    }
  }
}
}
​
GET blog/_search
{
"query": {
  "match": {
    "description": "集合"
  }
}
}
​
GET blog/_search
{
"query": {
  "match_all": {
     
  }
}
}
​
GET blog/_search
{
"query": {
  "wildcard": {
    "title": {
      "value": "SpringBoot从入门到?"
    }
  }
}
}
​
​
GET _analyze
{
"analyzer": "standard",
"text":"中华人民共和国"
}
​
​

在这里插入图片描述
IK分词器
ES默认的分词器处理中文不友好。默认一个字一个词。
IK分词 、庖丁解牛分词器…

GET _analyze
{
“analyzer”: “ik_max_word|ik_smart”,
“text”:“中华人民共和国”
}
ik_max_word:细粒度 [词条多]
ik_smart:粗粒度[词条少]
被查询的数据 name:华为荣耀P300移动50G手机 ik_max_word
用户输入的关键字: 华为手机 ik_smart
PUT blog
{
“mappings”: {
“properties”: {
“id”:{
“type”:“long”
},
“title”:{
“type”:“keyword”
},
“description”:{
“type”:“text”,
“analyzer”: “ik_max_word”,
“search_analyzer”: “ik_smart”

}

}
}
}

总结:
ES是什么?
全文检索
数据库查询存在问题
效率低 功能弱
Lucene --> solr / es关系
ES的安装
ES
postman/kibana
IK分词器
ES的概念
索引、 文档、 域 、 映射、 分词 、词条
kibana
索引的增删查
映射的新增、添加域、查询
文档的新增、修改、删除、查询
查询
根据ID查询
查询所有
term查询
match查询
ik
ik_smart
im_max_word

Elasticsearch第二天
内容回顾
ElasticSearch
全文检索[查询]
关系型数据库的查询存在的问题
》数据量大,索引一旦失效,数据库的查询效率非常非常低
》查询功能比较弱 “华为手机”
解决问题
倒排索引
数据在索引到索引库的过程中可以对数据进行分词
分词的结果是在索引库中多了一个词条和DocId的一个对应关系
“华为手机"关键字从词条中进行匹配,如果匹配到,根据词条获取DocId,根据DocId获取文档数据
在查询的过程中可以将"华为手机"也进行一个分词,分词后变成了"华为"和"手机”
全文检索,分词获取的词条是有限的,然后数据是无限。当数据远远大于词条的时候,搜索的频次会降低
词条进行索引
使用全文检索
》采集数据
数据---->Document[Field]—>分词器(分词)—>词条—>索引(index)
》数据检索
User—>keywords[关键字]—>Query—>索引(index)—>高亮展示/分组聚合统计…—>User
全文检索
Lucene
solr/elasticsearch
索引(index) 文件(document) 域(Field) 映射(Mapping)

使用Elasticsearch
环境准备
Elasticsearch
kibana / postman
ik
(1)创建索引
(2)添加一个Mapping
(3)查询索引
(4)删除索引
(5)创建索引时同时添加映射
(6)添加文档
(7)根据ID查询文档
(8)修改文档(添加文件,所添加文档的主键DocId是否存在,如果存在则修改[先删后加],如果不存在,直接添加)
(9)删除文档
Java的API方式来完成上述功能的所有操作。


列出技术
每个技术能做什么事
技术往壳子套,项目成型

(1)项目背景介绍
(2)项目架构
(3)项目的模块
(4)负责的模块
分析需求
设计表结构
代码开发
测试
测试文档
说明文档
上线支持
(5)准备项目中遇到的问题

今日内容
(1)创建索引
(2)添加一个Mapping
(3)查询索引
(4)删除索引
(5)创建索引时同时添加映射
(6)添加文档
(7)根据ID查询文档
(8)修改文档(添加文件,所添加文档的主键DocId是否存在,如果存在则修改[先删后加],如果不存在,直接添加)
(9)删除文档
public class EsTest {

private RestHighLevelClient client;
@Before
public void init(){
//1.建立和Es的连接
//host 192.168.200.131 port:9200
client = new RestHighLevelClient(RestClient.builder(
new HttpHost(“192.168.200.131”,9200)));
}
@After
public void destroy() throws Exception{
//4.关闭连接
client.close();
}
//创建索引
@Test
public void testCreateIndex() throws Exception{

//2.发送请求实现索引的创建
CreateIndexRequest createIndexRequest = new CreateIndexRequest(“blog_es”);
CreateIndexResponse response = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
//3.获取执行结果
boolean result = response.isAcknowledged();
System.out.println("=>"+result);


}
//添加一个Mapping
@Test
public void testPutMappingForIndex()throws Exception{
//为哪个索引添加映射
//映射在哪里?
String source="{\n" +
“\t"properties”:{\n" +
“\t\t"name”:{\n" +
“\t\t\t"type”:“keyword”\n" +
“\t\t},\n” +
“\t\t"age”:{\n" +
“\t\t\t"type”:“integer”\n" +
“\t\t},\n” +
“\t\t"address”:{\n" +
“\t\t\t"type”:“text”,\n" +
“\t\t\t"analyzer”:“ik_max_word”\n" +
“\t\t}\n” +
“\t}\n” +
“}”;
PutMappingRequest putMappingRequest = new PutMappingRequest(“blog_es”)
.source(source, XContentType.JSON);
//现在使用的是7.4.0,该版本已经不建议使用type类型
AcknowledgedResponse response = client.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
System.out.println("
=>"+response.isAcknowledged());
}
//查询索引
@Test
public void testQueryIndex() throws Exception{
GetIndexRequest getIndexRequest = new GetIndexRequest(“blog_es”);
GetIndexResponse response = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
String[] indices = response.getIndices();
System.out.println("
=>"+indices[0]);
Map<String, MappingMetaData> mappings = response.getMappings();
for (String key : mappings.keySet()) {
System.out.println("
>映射的Key"+key+"—映射的Value"+mappings.get(key).getSourceAsMap());
}
}

//判断索引是否存在
@Test
public void testExist()throws Exception{
GetIndexRequest getIndexRequest = new GetIndexRequest(“es_blog”);
boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
System.out.println("
>"+exists);
}
//删除索引
@Test
public void testDelIndex()throws Exception{

DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(“es_blog”);
AcknowledgedResponse response = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println("
>"+response.isAcknowledged());
}


//创建索引时同时添加映射
@Test
public void testCreateIndexWithMapping()throws Exception{

String source = “{\n” +
“\t"properties”:{\n" +
“\t\t"name”:{\n" +
“\t\t\t"type”:“keyword”\n" +
“\t\t},\n” +
“\t\t"age”:{\n" +
“\t\t\t"type”:“integer”\n" +
“\t\t},\n” +
“\t\t"address”:{\n" +
“\t\t\t"type”:“text”,\n" +
“\t\t\t"analyzer”:“ik_max_word”\n" +
“\t\t}\n” +
“\t}\n” +
“}”;
CreateIndexRequest createIndexRequest = new CreateIndexRequest(“es_blog”).mapping(source,XContentType.JSON);
CreateIndexResponse respone = client.indices().create(createIndexRequest,RequestOptions.DEFAULT);
System.out.println("
>"+respone.isAcknowledged());
}
//-------------上述所有的和索引相关的操作,使用的是client.indices()-------下面操作文档,需要使用client.index-
//添加文档
@Test
public void testAddDocByJson()throws Exception{
//文档内容在哪?
String source = “{“name”:“TOM”,“age”:118,“address”:“陕西西安草滩六路”}”;
IndexRequest indexRequest = new IndexRequest(“es_blog”).source(source,XContentType.JSON);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
//添加文档的时候,ID可以指定,也可以不指定,如果不指定,默认是自动创建一个随机唯一的ID
System.out.println(response.getId());
}

@Test
public void testAddDocByMap()throws Exception{
//文档内容在哪?
Map map = new HashMap();
map.put(“name”,“JERRY”);
map.put(“age”,200);
map.put(“address”,“广州深圳”);
IndexRequest indexRequest = new IndexRequest(“es_blog”).source(map).id(“1”);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
//添加文档的时候,ID可以指定,也可以不指定,如果不指定,默认是自动创建一个随机唯一的ID
System.out.println(response.getId());
}


@Test
public void testAddDocByDomain()throws Exception{
//文档内容在哪?
User user = new User();
user.setName(“小ROSE”);
//user---->json
String userJson = JSONObject.toJSONString(user);
IndexRequest indexRequest = new IndexRequest(“es_blog”).source(userJson,XContentType.JSON).id(“2”);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
//添加文档的时候,ID可以指定,也可以不指定,如果不指定,默认是自动创建一个随机唯一的ID
System.out.println(response.getId());
}

//根据ID查询文档

@Test
public void testFindByid()throws Exception {
GetRequest getRequest = new GetRequest(“es_blog”,“1”);
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(response.getSourceAsString()); //json字符串
System.out.println("
=");
System.out.println(response.getSourceAsMap());//map
}

//删除文档
@Test
public void testDelById()throws Exception{

DeleteRequest deleteRequest =new DeleteRequest(“es_blog”,“2”);
DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println("
>"+response.getId());
}

}

步骤:
(1)先有一个maven项目
(2)pom.xml添加对应的依赖
(3)学习对应的API来完成上述的所有操作
思考:如何在SpringBoot中使用API完成对应的业务操作???
1.添加springboot环境
parent spring-boot-starter-parent
dependency spring-boot-starter-web spring-boot-starter-test…
2.application.yml
es:
host: 192.168.200.131
port: 9200
3.EsConfig
@Configuration
@ConfigurationProperties(prefix = “es”)
public class EsConfig {

private String host;
private Integer port;


@Bean
public RestHighLevelClient restHighLevelClient(){

return new RestHighLevelClient(RestClient.builder(new HttpHost(host,port)));
}

public String getHost() {
return host;
}

public void setHost(String host) {
this.host = host;
}

public Integer getPort() {
return port;
}

public void setPort(Integer port) {
this.port = port;
}
}

4.注入RestHighLevelClient进行API调用
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsDemoApplication.class)
public class EsTest {

@Autowired
private RestHighLevelClient client;

}

_bulk
文档的增删改查
新增和ES交互一次
修改和ES交互一次
删除和ES交互一次
有没有一种办法,把上面所有的操作,封装起来,和ES交互一次就可以完成多个操作?
POST _bulk
{“action?”:{"_index":“indexName”,"_id":“docId”}}
create /index
{“name”:“xxx”,“age”:xx,“address”:“xxxxx”,“birthday”:xxx}
update
{“doc”:{“updateFieldName”:“updateFieldValue”}}
delete

POST _bulk
{“create”:{"_index":“person”,"_id":“1”}} #为person索引创建一个文档ID为1的文档
{“name”:“TOM”,“age”:18,“address”:“陕西西安”} # data 文件的内容 参考Mapping映射
{“create”:{"_index":“person”,"_id":“2”}} # 为person索引创建一个文档ID为2的文档
{“name”:“TOM”,“age”:19,“address”:“广州深圳”} # data 文件的内容 参考Mapping映射
{“update”:{"_index":“person”,"_id":“2”}} #修改 将person索引中文档ID为2的文件进行修改
{“doc”:{“name”:“JERRY”}} # 将name修改为JERRY
{“delete”:{"_index":“person”,"_id":“1”}} # 删除 将person索引中的文档ID为1的数据删除
{“index”:{"_index":“person”,"_id":“3”}} # 为person索引创建一个文档ID为3的文档
{“name”:“JERRY”,“age”:29,“address”:“湖南长沙”} # data 文件的内容 参考Mapping映射
下午:查询
(1)采集数据
从数据库表中将数据采集到索引库中。
步骤:
数据库
1.创建数据库database
create database es;
2.数据库中创建一个表table
create table goods (
id double , 主键
title varchar (300), 标题
price Decimal (22), 价格
stock double , 库存
saleNum double , 销量
createTime datetime , 创建时间
categoryName varchar (600), 分类名称
brandName varchar (300), 品牌名称
spec varchar (600) 规格
);
3.将数据添加到table中

4.执行select * from table能看到添加的数据。

索引库
1.创建一个索引库
PUT goods
2.为索引库添加映射

3.通过Java的API完成数据库中数据存入索引库
SpringBoot+Mybatis
实现数据库的查询

查询的数据会有一个列表集合
client.index();
client.bulk(); //效率高

测试
1.查询索引库将数据展示出来。

查询对象的名称
查询对象的作用
kibana使用查询对象
Java代理如何实现查询对象的使用。

matchAllQuery
作用:查询索引中的所有数据
分页:
前端到后台: currentPage pageSize
后台到前端: total list
GET goods/_search
{
“query”: {
“match_all”: {

}

},
“from”: 200, # (currentPage-1)*pageSize
“size”: 100 # pageSize
}

@Test
public void test()throws Exception{

    SearchRequest searchRequest = new SearchRequest("goods");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
            .query(QueryBuilders.matchAllQuery())
            .from(0)
            .size(100);


    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println("123456");

    SearchHits hits = response.getHits();
    if(hits!=null){
        long value = hits.getTotalHits().value;

        SearchHit[] hitArray = hits.getHits();
        if(hitArray!=null && hitArray.length>0){
            List<Goods> goodsList = new ArrayList<Goods>();
            for (SearchHit searchHit : hitArray) {
                String sourceAsString = searchHit.getSourceAsString();
                Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
                goodsList.add(goods);
            }
        }
        
    }
}

termQuery
查询对象的名称
查询对象的作用
拿着用户输入的关键字,到词条中进行精确匹配,如果匹配到返回对应的数据,匹配不到,返回Null
常用来数据类型为keyword的字段进行精确匹配。
kibana使用查询对象
GET goods/_search
{
“query”: {
“term”: {
“title”: {
“value”: “华为”
}
}
}
}

Java代理如何实现查询对象的使用。
@Test
public void test()throws Exception{

    SearchRequest searchRequest = new SearchRequest("goods");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
            .query(QueryBuilders.termQuery("fieldName","keywords"))
            .from(0)
            .size(100);


    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println("123456");

    SearchHits hits = response.getHits();
    if(hits!=null){
        long value = hits.getTotalHits().value;

        SearchHit[] hitArray = hits.getHits();
        if(hitArray!=null && hitArray.length>0){
            List<Goods> goodsList = new ArrayList<Goods>();
            for (SearchHit searchHit : hitArray) {
                String sourceAsString = searchHit.getSourceAsString();
                Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
                goodsList.add(goods);
            }
        }
        
    }
}

matchQuery
查询对象的名称
查询对象的作用
matchQuery:
把用户输入的关键字进行分词,获取词条[华为,手机],拿着分词后的结果再去匹配词条,将查询的结果取
交集(1)或者并集(1 2 3 4 5)进行返回

kibana使用查询对象
GET goods/_search
{
“query”: {
“match”: {
“title”: “华为手机”
}
}
}

GET goods/_search
{
“query”: {
“match”: {
“title”: {
“query”: “华为手机”,
“operator”: “and”
}
}
}
}

Java代理如何实现查询对象的使用。
@Test
public void test()throws Exception{

    SearchRequest searchRequest = new SearchRequest("goods");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
            .query(QueryBuilders.matchQuery("fieldName","keywords").operator(Operator.AND))
            .from(0)
            .size(100);


    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println("123456");

    SearchHits hits = response.getHits();
    if(hits!=null){
        long value = hits.getTotalHits().value;

        SearchHit[] hitArray = hits.getHits();
        if(hitArray!=null && hitArray.length>0){
            List<Goods> goodsList = new ArrayList<Goods>();
            for (SearchHit searchHit : hitArray) {
                String sourceAsString = searchHit.getSourceAsString();
                Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
                goodsList.add(goods);
            }
        }

    }
}

wildcardQuery: 模糊查询
注意:不要在keywords之前加 * ?
Mysql: 张% 张某某某… 张_ 张某
%:零个或多个
_:一个
ES:
:零个或多个
?:一个

QueryBuilders.wildcardQuery(“filedName”,“keywords”);

prefixQuery
以对应的前缀开始查找,类似于wildcardQuery中的 xxx.*

QueryBuilders.prefixQuery(“filedName”,“keywords”);

regexpQuery
正则查询,条件支持正则表达式
QueryBuilders.regexpQuery(“filedName”,“keywords”);

rangeQuery范围查询
rangQuery
gt > great
lt < less
gte >= great than equal
lte <= less than equal
GET goods/_search
{
“query”: {
“range”: {
“price”: {
“gte”: 10,
“lte”: 200
}
}
},
“sort”: [
{
“price”: {
“order”: “asc”
}
}
]
}
@Test
public void test()throws Exception{

    SearchRequest searchRequest = new SearchRequest("goods");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
            .query(QueryBuilders.rangeQuery("price").gt(10).lt(100))
            .from(1)
            .size(100)
            .sort("price", SortOrder.ASC);


    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println("123456");

    SearchHits hits = response.getHits();
    if(hits!=null){
        long value = hits.getTotalHits().value;

        SearchHit[] hitArray = hits.getHits();
        if(hitArray!=null && hitArray.length>0){
            List<Goods> goodsList = new ArrayList<Goods>();
            for (SearchHit searchHit : hitArray) {
                String sourceAsString = searchHit.getSourceAsString();
                Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
                goodsList.add(goods);
            }
        }

    }
}

QueryStringQuery
一个keywords可以去匹配多个域进行查询。
GET goods/_search
{
“query”: {
“query_string”: {
“fields”: [“title”,“brandName”],
“query”: “华为 AND 手机”
}
}
}
GET goods/_search
{
“query”: {
“simple_query_string”: {
“fields”: [“title”,“brandName”],
“query”: “华为 AND 手机”
}
}
@Test
public void test()throws Exception{

    SearchRequest searchRequest = new SearchRequest("goods");

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
            .query(QueryBuilders.queryStringQuery("keywords").field("").defaultOperator(Operator.AND))
            .from(1)
            .size(100)
            .sort("price", SortOrder.ASC);


    searchRequest.source(searchSourceBuilder);

    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

    System.out.println("123456");

    SearchHits hits = response.getHits();
    if(hits!=null){
        long value = hits.getTotalHits().value;

        SearchHit[] hitArray = hits.getHits();
        if(hitArray!=null && hitArray.length>0){
            List<Goods> goodsList = new ArrayList<Goods>();
            for (SearchHit searchHit : hitArray) {
                String sourceAsString = searchHit.getSourceAsString();
                Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
                goodsList.add(goods);
            }
        }

    }
}
内容回顾 测试代码
package live.longmarch.test;

import com.alibaba.fastjson.JSONObject;
import live.longmarch.SpringBootDemo2Application;

import live.longmarch.domain.User;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
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.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @PackageName: live.longmarch.test
 * @ClassName: ElasticsearchTest
 * @Author: raven
 * @Date: 2020/2/5 14:38
 * @Blame: liunian
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootDemo2Application.class)
public class ElasticsearchTest {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
//================================Index=================================

    /**
     * 创建一个索引库
     */
    @Test
    public void testCreateIndex() throws IOException {
        // 发送请求实现索引的创建
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("blog");
        CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        // 获取执行结果
        boolean acknowledged = response.isAcknowledged();
        System.out.println("是否创建成功:" + acknowledged);
    }

    /**
     * 获取索引库
     */
    @Test
    public void testGetIndex() throws Exception {
        GetIndexRequest getIndexRequest = new GetIndexRequest("blog");
        GetIndexResponse response = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        // 获取索引库信息
        String[] indices = response.getIndices();
        for (String index : indices) {
            System.out.println(index);
        }
//        response.getMappings()  获取当前索引库的映射关系
    }

    /**
     * 删除索引库
     */
    @Test
    public void testDelIndex() throws Exception {
        // 设置需要删除的索引库
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("blog");
        AcknowledgedResponse response = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        // 获取删除结果
        boolean acknowledged = response.isAcknowledged();
        System.out.println("是否删除成功?" + acknowledged);
    }

    /**
     * 判断索引库是否存在
     */
    @Test
    public void testExistIndex() throws Exception {
        // 设置需要判断的索引库
        GetIndexRequest getIndexRequest = new GetIndexRequest("blog");
        boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        // 获取判断结果
        // true 存在, false 不存在
        System.out.println("索引库是否存在?---》" + exists);
    }

    //================================mapping=============================

    /**
     * 当索引已经存在的时候添加映射关系
     *
     * @throws Exception 异常
     */
    @Test
    public void testAddMappingForIndex() throws Exception {
        // 2.创建json字符串
        String source = "{\n" +
                "\t\"properties\":{\n" +
                "\t\t\"name\":{\n" +
                "\t\t\t\"type\":\"keyword\"\n" +
                "\t\t},\n" +
                "\t\t\"address\":{\n" +
                "\t\t   \"type\":\"text\"\n" +
                "\t\t}\n" +
                "\t}\n" +
                "}";
        // 1.根据索引库名称创建映射关系
        PutMappingRequest putMappingRequest = new PutMappingRequest("blog")
                .source(source, XContentType.JSON);
        AcknowledgedResponse response = restHighLevelClient.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
        // 3.判断映射关系是否添加成功
        boolean acknowledged = response.isAcknowledged();
        System.out.println("映射添加成功?==》" + acknowledged);
    }

    /**
     * 创建索引库的时候添加映射关系
     */
    @Test
    public void testAddMappingForIndex2() throws Exception {
        // 2.创建映射关系
        String source = "{\n" +
                "\t\"properties\":{\n" +
                "\t\t\"name\":{\n" +
                "\t\t\t\"type\":\"keyword\"\n" +
                "\t\t},\n" +
                "\t\t\"age\":{\n" +
                "\t\t\t\"type\":\"integer\"\n" +
                "\t\t},\n" +
                "\t\t\"address\":{\n" +
                "\t\t\t\"type\":\"text\",\n" +
                "\t\t\t\"analyzer\":\"ik_max_word\"\n" +
                "\t\t}\n" +
                "\t}\n" +
                "}";

        // 1.创建索引库
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("my_blog").mapping(source, XContentType.JSON);
        CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        // 3.判断是否创建索引库成功
        boolean acknowledged = response.isAcknowledged();
        System.out.println("索引库创建成功? === 》" + acknowledged);
    }

    //===========================文档======================================

    /**
     * 添加文档  通过json字符串的方式进行添加
     */
    @Test
    public void addDocByJson() throws Exception {
        // 2.设置文档内容 通过json字符串的方式进行添加文档
        String source = "{\n" +
                "  \"name\":\"张三丰\",\n" +
                "  \"address\":\"武当山峰顶白云观\"\n" +
                "}";
        // 1.添加文档
        IndexRequest indexRequest = new IndexRequest("blog")
                .id("1")  //ID可以指定可以不指定,如果不指定默认给一个唯一字符串
                .source(source, XContentType.JSON);
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    }

    /**
     * 添加文档, 通过map的方式进行添加文档
     *
     * @throws Exception
     */
    @Test
    public void addDocByMap() throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("name", "张三丰");
        map.put("address", "武当山峰顶白云观");
        IndexRequest indexRequest = new IndexRequest("blog")
                .id("2")
                .source(map);
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    }

    /**
     * 添加文档,通过封装对象的方式进行添加
     */
    @Test
    public void addDocByDomain() throws Exception {

        User user = new User();
        user.setName("张三丰");
        user.setAddress("武当山峰顶白云观");
        //user对象--->json字符串
        String userJson = JSONObject.toJSONString(user);
        IndexRequest indexRequest = new IndexRequest("blog")
                .id("3")  //ID可以指定可以不指定,如果不指定默认给一个唯一字符串
                //添加文档source有三种方式   Map  /  json字符串/ domain
                .source(userJson, XContentType.JSON);
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    }

    /**
     * 根据id查询文档
     */
    @Test
    public void getDocById() throws Exception {
        GetRequest getRequest = new GetRequest("blog", "1");
        GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString());
    }

    /**
     * 根据id 删除
     */
    @Test
    public void delById() throws Exception {
        DeleteRequest deleteRequest = new DeleteRequest("blog", "1");
        DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
    }

    //======================================重点 要点 难度【复杂的查询】====================================
    //查询所有
    //分页
    //排序
    //分组
    //高亮展示
    //单条件查询
    //多条件查询

    //如何设置查询相关的信息
    //查询所有:
//        termQuery
//              词条精确匹配
//
//         matchQuery
//
//        wildcardQuery
//
//         matchAllQuery
//
//        rangeQuery
//
//        queryStringQuery
//
//        boolQuery

    /**
     * termQuery 精确匹配
     * @throws Exception
     */
    @Test
    public void testTermSearch() throws Exception {

        // 2.创建searchRequest请求
        SearchRequest searchRequest = new SearchRequest("blog");
        // 3.创建SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.termQuery("name", "张三丰"))
                //分页:前端到后台  currentPage  pageSize   后台到前端: list  total;
                .from(0) //(currentPage-1)*pageSize
                .size(10) // pageSize
                .sort("name", SortOrder.ASC); // 排序
        searchRequest.source(searchSourceBuilder);
        // 1.进行查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // debug
        SearchHits hits = response.getHits();
        if (hits != null) {
            TotalHits totalHits = hits.getTotalHits(); // 总记录数
            SearchHit[] hitArray = hits.getHits();
            if (hitArray != null && hitArray.length > 0){
                for (SearchHit searchHit : hitArray) {
                    String sourceAsString = searchHit.getSourceAsString();
                    System.out.println(sourceAsString);
                }
            }
        }
    }

    /**
     * matchQuery 分词查询
     * @throws Exception
     */
    @Test
    public void testMatchQuerySearch() throws Exception {

        // 2.创建searchRequest请求
        SearchRequest searchRequest = new SearchRequest("blog");
        // 3.创建SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchQuery("address", "武当山"))
                //分页:前端到后台  currentPage  pageSize   后台到前端: list  total;
                .from(0) //(currentPage-1)*pageSize
                .size(10) // pageSize
                .sort("name", SortOrder.ASC); // 排序
        searchRequest.source(searchSourceBuilder);
        // 1.进行查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // debug
        SearchHits hits = response.getHits();
        if (hits != null) {
            TotalHits totalHits = hits.getTotalHits(); // 总记录数
            SearchHit[] hitArray = hits.getHits();
            if (hitArray != null && hitArray.length > 0){
                for (SearchHit searchHit : hitArray) {
                    String sourceAsString = searchHit.getSourceAsString();
                    System.out.println(sourceAsString);
                }
            }
        }
    }

    /**
     * matchAllQuery 查询所有
     * @throws Exception
     */
    @Test
    public void testMatchAllQuerySearch() throws Exception {

        // 2.创建searchRequest请求
        SearchRequest searchRequest = new SearchRequest("blog");
        // 3.创建SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery())
                //分页:前端到后台  currentPage  pageSize   后台到前端: list  total;
                .from(0) //(currentPage-1)*pageSize
                .size(10) // pageSize
                .sort("name", SortOrder.ASC); // 排序
        searchRequest.source(searchSourceBuilder);
        // 1.进行查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // debug
        SearchHits hits = response.getHits();
        if (hits != null) {
            TotalHits totalHits = hits.getTotalHits(); // 总记录数
            SearchHit[] hitArray = hits.getHits();
            if (hitArray != null && hitArray.length > 0){
                for (SearchHit searchHit : hitArray) {
                    String sourceAsString = searchHit.getSourceAsString();
                    System.out.println(sourceAsString);
                }
            }
        }
    }

    /**
     * wildcardQuery 模糊查询
     * prefixQuery
     *     以对应的前缀开始查找,类似于wildcardQuery中的 xxx.*
     *
     * QueryBuilders.prefixQuery("filedName","keywords");
     *
     * regexpQuery
     *     正则查询,条件支持正则表达式
     * QueryBuilders.regexpQuery("filedName","keywords");
     * @throws Exception
     */
    @Test
    public void testWildcardQueryQuerySearch() throws Exception {

        // 2.创建searchRequest请求
        SearchRequest searchRequest = new SearchRequest("blog");
        // 3.创建SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
                /**
                 * ES:
                 *     *:零个或多个
                 *     ?:一个*
                 */
                .query(QueryBuilders.wildcardQuery("address","武当?"))
                //分页:前端到后台  currentPage  pageSize   后台到前端: list  total;
                .from(0) //(currentPage-1)*pageSize
                .size(10) // pageSize
                .sort("name", SortOrder.ASC); // 排序
        searchRequest.source(searchSourceBuilder);
        // 1.进行查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // debug
        SearchHits hits = response.getHits();
        if (hits != null) {
            TotalHits totalHits = hits.getTotalHits(); // 总记录数
            SearchHit[] hitArray = hits.getHits();
            if (hitArray != null && hitArray.length > 0){
                for (SearchHit searchHit : hitArray) {
                    String sourceAsString = searchHit.getSourceAsString();
                    System.out.println(sourceAsString);
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值