当前位置:   article > 正文

SpringCloud微服务(三)RabbitMQ、SpringAMQP、elasticsearch、DSL、MQ、ES详细介绍_es和mq

es和mq

目录

一、初始MQ

同步调用

异步调用

什么是MQ

执行下面的命令来运行MQ容器:

如果冲突了,可以先查询

RabbitMQ概述 

常见消息模型

HelloWorld案例

二、SpringAMQP

引入依赖

Work Queue 

消费预取限制

​编辑 发布、订阅

发布订阅Fanout Exchange

发布DirectExchange

发布订阅TopicExchange 

消息转化器

MQ代码

三、什么是elasticsearch

 正向索引

倒排索引

文档

索引

概念对比

架构 

 ​编辑

部署单点es

1.2.加载镜像

1.3.运行

命令解释:

2.1.部署

 分词器

2.2.DevTools

kibana中提供了一个DevTools界面:

3.安装IK分词器

3.1.在线安装ik插件(较慢)

3.2.离线安装ik插件(推荐)

1)查看数据卷目录

2)解压缩分词器安装包

3)上传到es容器的插件数据卷中

4)重启容器

5)测试:

3.3 扩展词词典

四、索引库操作 

创建索引库

查看、删除索引库​编辑

修改索引库

 新增文档​编辑

 查看、删除文档​编辑

修改文档

RestClient操作索引库

索引库代码

RestClient操作文档

操作文档代码

DSL 查询文档

 DSL  Query的分类​编辑

DSL Query基本语法

 全文检索查询​编辑

 精确查询​编辑

 地理查询​编辑

相关性算分

 Function Score Query​编辑

复合查询 Boolean Query

 搜索结果处理​编辑

分页

深度分页问题

​编辑高亮 

RestClient查询文档

全文检索查询

精确查询 ​编辑

符合查询

排序和分页

 高亮​编辑


初始MQ

同步调用

异步调用

什么是MQ

执行下面的命令来运行MQ容器:

  1. docker run \
  2. -e RABBITMQ_DEFAULT_USER=itcast \
  3. -e RABBITMQ_DEFAULT_PASS=123321 \
  4. --name mq \
  5. --hostname mq1 \
  6. -p 15672:15672 \
  7. -p 5672:5672 \
  8. -d \
  9. rabbitmq:3-management

如果冲突了,可以先查询

RabbitMQ概述 

常见消息模型

HelloWorld案例

 

SpringAMQP

 

引入依赖

 

Work Queue 

 

 

消费预取限制

 发布、订阅

发布订阅Fanout Exchange

发布DirectExchange

发布订阅TopicExchange 

 

 

消息转化器

MQ代码

  1. @Component
  2. public class SpringRabbitListener {
  3. // @RabbitListener(queues = "simple.queue")
  4. // public void listenSimpleQueue(String msg){
  5. // System.out.println("消费者接收到simple.queue的消息:["+msg+"]");
  6. //
  7. // }
  8. @RabbitListener(queues = "simple.queue")
  9. public void listenWorkQueue1(String msg) throws InterruptedException {
  10. System.out.println("消费者1接收到simple.queue的消息:["+msg+"]"+ LocalTime.now());
  11. Thread.sleep(20);
  12. }
  13. @RabbitListener(queues = "simple.queue")
  14. public void listenWorkQueue2(String msg) throws InterruptedException {
  15. System.err.println("消费者2接收到simple.queue的消息:["+msg+"]"+LocalTime.now());
  16. Thread.sleep(200);
  17. }
  18. @RabbitListener(queues = "fanout.queue1")
  19. public void listenFanoutQueue1(String msg){
  20. System.out.println("消费者接收到fanout.queue1的消息:["+msg+"]");
  21. }
  22. @RabbitListener(queues = "fanout.queue2")
  23. public void listenFanoutQueue2(String msg){
  24. System.out.println("消费者接收到fanout.queue2的消息:["+msg+"]");
  25. }
  26. @RabbitListener(bindings = @QueueBinding(
  27. value = @Queue(name = "direct.queue1"),
  28. exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
  29. key = {"red","blue"}
  30. ))
  31. public void listenDirectQueue1(String msg){
  32. System.out.println("消费者接收到direct.queue1的消息:["+msg+"]");
  33. }
  34. @RabbitListener(bindings = @QueueBinding(
  35. value = @Queue(name = "direct.queue2"),
  36. exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
  37. key = {"red","yellow"}
  38. ))
  39. public void listenDirectQueue2(String msg){
  40. System.out.println("消费者接收到direct.queue2的消息:["+msg+"]");
  41. }
  42. @RabbitListener(bindings = @QueueBinding(
  43. value = @Queue(name = "topic.queue1"),
  44. exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
  45. key = "china.#"
  46. ))
  47. public void listenTopicQueue1(String msg){
  48. System.out.println("消费者接收到topic.queue1的消息:["+msg+"]");
  49. }
  50. @RabbitListener(bindings = @QueueBinding(
  51. value = @Queue(name = "topic.queue2"),
  52. exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
  53. key = "#.news"
  54. ))
  55. public void listenTopicQueue2(String msg){
  56. System.out.println("消费者接收到topic.queue2的消息:["+msg+"]");
  57. }
  58. @RabbitListener(queues = "object.queue")
  59. public void listObjectQueue(Map<String,Object> msg){
  60. System.out.println("接收object.queue的消息:"+msg);
  61. }
  62. }
  1. @Configuration
  2. public class FanoutConfig {
  3. //声明FanoutExchange 交换机
  4. //itcast.fanout
  5. @Bean
  6. public FanoutExchange fanoutExchange(){
  7. return new FanoutExchange("itcast.fanout");
  8. }
  9. //声明一个队列fanout.queue1
  10. @Bean
  11. public Queue fanoutQueue1(){
  12. return new Queue("fanout.queue1");
  13. }
  14. //绑定队列1和交换机
  15. @Bean
  16. public Binding fanoutBinding1(Queue fanoutQueue1,FanoutExchange fanoutExchange){
  17. return BindingBuilder
  18. .bind(fanoutQueue1)
  19. .to(fanoutExchange);
  20. }
  21. //fanout.queue2
  22. //声明一个队列fanout.queue1
  23. @Bean
  24. public Queue fanoutQueue2(){
  25. return new Queue("fanout.queue2");
  26. }
  27. //绑定队列1和交换机
  28. @Bean
  29. public Binding fanoutBinding2(Queue fanoutQueue2,FanoutExchange fanoutExchange){
  30. return BindingBuilder
  31. .bind(fanoutQueue2)
  32. .to(fanoutExchange);
  33. }
  34. @Bean
  35. public Queue objectQueue(){
  36. return new Queue("object.queue");
  37. }
  38. }
  1. @SpringBootApplication
  2. public class ConsumerApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(ConsumerApplication.class, args);
  5. }
  6. @Bean
  7. public MessageConverter messageConverter(){
  8. return new Jackson2JsonMessageConverter();
  9. }
  10. }
  1. public class PublisherTest {
  2. @Test
  3. public void testSendMessage() throws IOException, TimeoutException {
  4. // 1.建立连接
  5. ConnectionFactory factory = new ConnectionFactory();
  6. // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码
  7. factory.setHost("虚拟机地址");
  8. factory.setPort(5672);
  9. factory.setVirtualHost("/");
  10. factory.setUsername("itcast");
  11. factory.setPassword("123321");
  12. // 1.2.建立连接
  13. Connection connection = factory.newConnection();
  14. // 2.创建通道Channel
  15. Channel channel = connection.createChannel();
  16. // 3.创建队列
  17. String queueName = "simple.queue";
  18. channel.queueDeclare(queueName, false, false, false, null);
  19. // 4.发送消息
  20. String message = "hello, rabbitmq!";
  21. channel.basicPublish("", queueName, null, message.getBytes());
  22. System.out.println("发送消息成功:【" + message + "】");
  23. // 5.关闭通道和连接
  24. channel.close();
  25. connection.close();
  26. }
  27. }
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class SpringAmqpTest {
  4. @Autowired
  5. private RabbitTemplate rabbitTemplate;
  6. @Test
  7. public void testSendMessage2SimpleWueue(){
  8. String queueName = "simple.queue";
  9. String message = "hello,spring amqp!!!";
  10. rabbitTemplate.convertAndSend(queueName,message);
  11. }
  12. @Test
  13. public void testSendMessage2WorkQueue() throws InterruptedException {
  14. String queueName = "simple.queue";
  15. String message = "hello,message__";
  16. for ( int i = 1; i <= 50; i++ ) {
  17. rabbitTemplate.convertAndSend(queueName,message+i);
  18. Thread.sleep(20);
  19. }
  20. }
  21. @Test
  22. public void testSendFanoutExchange(){
  23. //交换机名称
  24. String exchangeName = "itcast.fanout";
  25. //消息
  26. String message = "hello,every one !";
  27. //发送消息
  28. rabbitTemplate.convertAndSend(exchangeName,"",message);
  29. }
  30. @Test
  31. public void testSendDirectExchange(){
  32. //交换机名称
  33. String exchangeName = "itcast.direct";
  34. //消息
  35. String message = "hello,blue !";
  36. //发送消息
  37. rabbitTemplate.convertAndSend(exchangeName,"red",message);
  38. }
  39. @Test
  40. public void testSendTopicExchange(){
  41. //交换机名称
  42. String exchangeName = "itcast.topic";
  43. //消息
  44. String message = "中国NO.1";
  45. //发送消息
  46. rabbitTemplate.convertAndSend(exchangeName,"chi.weather",message);
  47. }
  48. @Test
  49. public void testSendObjectExchange(){
  50. HashMap<String, Object> msg = new HashMap<>();
  51. msg.put("name","留言2");
  52. msg.put("age",21);
  53. //发送消息
  54. rabbitTemplate.convertAndSend("object.queue",msg);
  55. }
  56. }

什么是elasticsearch

 

 

 正向索引

倒排索引

 

文档

索引

概念对比

架构 

 

 

部署单点es

因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:

docker network create es-net

1.2.加载镜像

这里我们采用elasticsearch的7.12.1版本的镜像,这个镜像体积非常大,接近1G。不建议大家自己pull。

课前资料提供了镜像的tar包:

 大家将其上传到虚拟机中,然后运行命令加载即可:

  1. # 导入数据
  2. docker load -i es.tar

同理还有kibana的tar包也需要这样做。

1.3.运行

运行docker命令,部署单点es:

  1. docker run -d \
  2. --name es \
  3. -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  4. -e "discovery.type=single-node" \
  5. -v es-data:/usr/share/elasticsearch/data \
  6. -v es-plugins:/usr/share/elasticsearch/plugins \
  7. --privileged \
  8. --network es-net \
  9. -p 9200:9200 \
  10. -p 9300:9300 \
  11. elasticsearch:7.12.1

命令解释:

  • -e "cluster.name=es-docker-cluster":设置集群名称

  • -e "http.host=0.0.0.0":监听的地址,可以外网访问

  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":内存大小

  • -e "discovery.type=single-node":非集群模式

  • -v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录

  • -v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录

  • -v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录

  • --privileged:授予逻辑卷访问权

  • --network es-net :加入一个名为es-net的网络中

  • -p 9200:9200:端口映射配置

在浏览器中输入:http://192.168.150.101:9200 即可看到elasticsearch的响应结果:

 kibana可以给我们提供一个elasticsearch的可视化界面,便于我们学习。

2.1.部署

运行docker命令,部署kibana(版本一定要一样)

  1. docker run -d \
  2. --name kibana \
  3. -e ELASTICSEARCH_HOSTS=http://es:9200 \
  4. --network=es-net \
  5. -p 5601:5601 \
  6. kibana:7.12.1
  • --network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中

  • -e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch

  • -p 5601:5601:端口映射配置

kibana启动一般比较慢,需要多等待一会,可以通过命令:

docker logs -f kibana

查看运行日志,当查看到下面的日志,说明成功:

 分词器

2.2.DevTools

kibana中提供了一个DevTools界面:

 这个界面中可以编写DSL来操作elasticsearch。并且对DSL语句有自动补全功能。

3.安装IK分词器

3.1.在线安装ik插件(较慢)

  1. # 进入容器内部
  2. docker exec -it elasticsearch /bin/bash
  3. # 在线下载并安装
  4. ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip
  5. #退出
  6. exit
  7. #重启容器
  8. docker restart elasticsearch

3.2.离线安装ik插件(推荐)

1)查看数据卷目录

安装插件需要知道elasticsearch的plugins目录位置,而我们用了数据卷挂载,因此需要查看elasticsearch的数据卷目录,通过下面命令查看:

docker volume inspect es-plugins

显示结果:

  1. [
  2. {
  3. "CreatedAt": "2022-05-06T10:06:34+08:00",
  4. "Driver": "local",
  5. "Labels": null,
  6. "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
  7. "Name": "es-plugins",
  8. "Options": null,
  9. "Scope": "local"
  10. }
  11. ]

说明plugins目录被挂载到了:/var/lib/docker/volumes/es-plugins/_data这个目录中。

2)解压缩分词器安装包

下面我们需要把课前资料中的ik分词器解压缩,重命名为ik

3)上传到es容器的插件数据卷中

4)重启容器

  1. # 4、重启容器
  2. docker restart es
  3. # 查看es日志
  4. docker logs -f es

5)测试:

IK分词器包含两种模式:

  • ik_smart:最少切分

  • ik_max_word:最细切分

  1. GET /_analyze
  2. {
  3. "analyzer": "ik_max_word",
  4. "text": "我爱学习java太棒了"
  5. }

结果:

  1. {
  2. "tokens" : [
  3. {
  4. "token" : "我",
  5. "start_offset" : 0,
  6. "end_offset" : 1,
  7. "type" : "CN_CHAR",
  8. "position" : 0
  9. },
  10. {
  11. "token" : "爱学习",
  12. "start_offset" : 1,
  13. "end_offset" : 4,
  14. "type" : "CN_WORD",
  15. "position" : 1
  16. },
  17. {
  18. "token" : "学习",
  19. "start_offset" : 2,
  20. "end_offset" : 4,
  21. "type" : "CN_WORD",
  22. "position" : 2
  23. },
  24. {
  25. "token" : "java",
  26. "start_offset" : 4,
  27. "end_offset" : 8,
  28. "type" : "ENGLISH",
  29. "position" : 3
  30. },
  31. {
  32. "token" : "太棒了",
  33. "start_offset" : 8,
  34. "end_offset" : 11,
  35. "type" : "CN_WORD",
  36. "position" : 4
  37. },
  38. {
  39. "token" : "太棒",
  40. "start_offset" : 8,
  41. "end_offset" : 10,
  42. "type" : "CN_WORD",
  43. "position" : 5
  44. },
  45. {
  46. "token" : "了",
  47. "start_offset" : 10,
  48. "end_offset" : 11,
  49. "type" : "CN_CHAR",
  50. "position" : 6
  51. }
  52. ]
  53. }

3.3 扩展词词典

随着互联网的发展,“造词运动”也越发的频繁。出现了很多新的词语,在原有的词汇列表中并不存在。比如:“奥力给”,“传智播客” 等。

所以我们的词汇也需要不断的更新,IK分词器提供了扩展词汇的功能。

1)打开IK分词器config目录:

 2)在IKAnalyzer.cfg.xml配置文件内容添加:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  3. <properties>
  4. <comment>IK Analyzer 扩展配置</comment>
  5. <!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
  6. <entry key="ext_dict">ext.dic</entry>
  7. </properties>

索引库操作 

创建索引库

  1. #创建索引库
  2. PUT /heihei
  3. {
  4. "mappings": {
  5. "properties": {
  6. "info": {
  7. "type": "text",
  8. "analyzer": "ik_smart"
  9. },
  10. "email": {
  11. "type": "keyword",
  12. "index": false
  13. },
  14. "name": {
  15. "type": "object",
  16. "properties": {
  17. "firstName": {
  18. "type": "keyword"
  19. },
  20. "lastName": {
  21. "type": "keyword"
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }

查看、删除索引库

 

修改索引库

 

 

 

 新增文档

 查看、删除文档

修改文档

 

RestClient操作索引库

 

 

  1. #酒店的mapping
  2. PUT /hotel
  3. {
  4. "mappings": {
  5. "properties": {
  6. "id":{
  7. "type": "keyword"
  8. },
  9. "name":{
  10. "type": "text",
  11. "analyzer": "ik_max_word"
  12. },
  13. "adress":{
  14. "type": "keyword",
  15. "index": false
  16. },
  17. "price":{
  18. "type": "integer"
  19. },
  20. "score":{
  21. "type": "integer"
  22. },
  23. "brand":{
  24. "type": "keyword"
  25. },
  26. "city":{
  27. "type": "keyword"
  28. },
  29. "starName":{
  30. "type": "keyword"
  31. },
  32. "business":{
  33. "type": "keyword"
  34. },
  35. "location":{
  36. "type": "geo_point"
  37. },
  38. "pic":{
  39. "type": "keyword",
  40. "index": false
  41. }
  42. }
  43. }
  44. }

索引库代码

  1. public class HotelIndexTest {
  2. private RestHighLevelClient client;
  3. @Test
  4. void testInit(){
  5. System.out.println(client);
  6. }
  7. @Test
  8. void createHotelIndex() throws IOException {
  9. //1.创建Request对象
  10. CreateIndexRequest request = new CreateIndexRequest("hotel");
  11. //2.准备请求的参数,DSL语句
  12. request.source(MAPPTING_TEMPLATE, XContentType.JSON);
  13. //3.发送请求
  14. client.indices().create(request, RequestOptions.DEFAULT);
  15. }
  16. @Test
  17. void deleteHotelIndex() throws IOException {
  18. //1.创建Request对象
  19. DeleteIndexRequest request = new DeleteIndexRequest("hotel");
  20. //3.发送请求
  21. client.indices().delete(request, RequestOptions.DEFAULT);
  22. }
  23. @Test
  24. void testExistHotelIndex() throws IOException {
  25. //1.创建Request对象
  26. GetIndexRequest request = new GetIndexRequest("hotel");
  27. boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
  28. //3.发送请求
  29. System.err.println(exists ? "索引库已经存在" : "索引库不存在!");
  30. }
  31. @BeforeEach
  32. void setUp(){
  33. this.client = new RestHighLevelClient(
  34. RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")
  35. ));
  36. }
  37. @AfterEach
  38. void tearDown()throws IOException{
  39. this.client.close();
  40. }
  41. }

RestClient操作文档

 

 

 

操作文档代码

  1. @SpringBootTest
  2. public class HotelDocumentTest {
  3. @Autowired
  4. private IHotelService hotelService;
  5. private RestHighLevelClient client;
  6. @Test
  7. void testAddDcoument() throws IOException {
  8. //根据id查询酒店数据
  9. Hotel hotel = hotelService.getById(36934L);
  10. //转化为文档类型
  11. HotelDoc hotelDoc = new HotelDoc(hotel);
  12. //1.准备Request对象
  13. IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
  14. //2.准备Json文件
  15. request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
  16. client.index(request,RequestOptions.DEFAULT);
  17. //3.发送请求
  18. }
  19. @Test
  20. void testGetDocumentById() throws IOException {
  21. //1.准备Request
  22. GetRequest request = new GetRequest("hotel", "36934");
  23. //2.发送请求,得到响应
  24. GetResponse response = client.get(request, RequestOptions.DEFAULT);
  25. //3.解析响应结果
  26. String json = response.getSourceAsString();
  27. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
  28. System.out.println(hotelDoc);
  29. }
  30. @Test
  31. void testRulkRequest() throws IOException {
  32. //批量查询酒店数据
  33. List<Hotel> hotels = hotelService.list();
  34. //1.创建Request
  35. BulkRequest request = new BulkRequest();
  36. //2.准备参数,添加多个新增的Request
  37. for ( Hotel hotel : hotels ) {
  38. //转换为文档类型HotelDoc
  39. HotelDoc hotelDoc = new HotelDoc(hotel);
  40. //2.准备参数,添加多个新增的Request
  41. request.add(new IndexRequest("hotel")
  42. .id(hotel.getId().toString())
  43. .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
  44. }
  45. //3.发送请求
  46. client.bulk(request,RequestOptions.DEFAULT);
  47. }
  48. @Test
  49. void testUpdateDocumentById() throws IOException {
  50. //1.准备Request
  51. UpdateRequest request = new UpdateRequest("hotel", "36934");
  52. //2.准备请求参数
  53. request.doc(
  54. "price","952",
  55. "starName","五钻"
  56. );
  57. //2.发送请求,得到响应
  58. client.update(request, RequestOptions.DEFAULT);
  59. //3.解析响应结果
  60. }
  61. @Test
  62. void testDeleteDocumentById() throws IOException {
  63. List<Hotel> list = hotelService.list();
  64. //循环删除
  65. for ( Hotel hotel : list ) {
  66. //1.准备Request
  67. DeleteRequest request = new DeleteRequest("hotel", hotel.getId().toString());
  68. //2.发送请求,得到响应
  69. client.delete(request, RequestOptions.DEFAULT);
  70. }
  71. //1.准备Request
  72. DeleteRequest request = new DeleteRequest("hotel", "36934");
  73. //2.发送请求,得到响应
  74. client.delete(request, RequestOptions.DEFAULT);
  75. }
  76. @BeforeEach
  77. void setUp(){
  78. this.client = new RestHighLevelClient(
  79. RestClient.builder(HttpHost.create("http://虚机机地址:es端口")
  80. ));
  81. }
  82. @AfterEach
  83. void tearDown()throws IOException{
  84. this.client.close();
  85. }
  86. }

DSL 查询文档

 

 DSL  Query的分类

DSL Query基本语法

 全文检索查询

  1. GET /hotel/_doc/36934
  2. #查询所有
  3. GET /hotel/_search
  4. {
  5. "query": {
  6. "match_all": {}
  7. }
  8. }
  9. #math查询
  10. GET /hotel/_search
  11. {
  12. "query": {
  13. "match": {
  14. "all": "外滩如家"
  15. }
  16. }
  17. }
  18. #multi_math查询
  19. GET /hotel/_search
  20. {
  21. "query": {
  22. "multi_match": {
  23. "query": "外滩如家",
  24. "fields": ["brand","name","business"]
  25. }
  26. }
  27. }

 精确查询

 

  1. #term查询
  2. GET /hotel/_search
  3. {
  4. "query": {
  5. "term": {
  6. "city": {
  7. "value": "上海"
  8. }
  9. }
  10. }
  11. }
  12. #range查询 几个e代表等于
  13. GET /hotel/_search
  14. {
  15. "query": {
  16. "range": {
  17. "price": {
  18. "gte": 1000,
  19. "lte": 3000
  20. }
  21. }
  22. }
  23. }

 地理查询

 

 

  1. #distance查询
  2. GET /hotel/_search
  3. {
  4. "query": {
  5. "geo_distance": {
  6. "distance":"3km",
  7. "location":"31.219306, 121.445427"
  8. }
  9. }
  10. }

相关性算分

 

 Function Score Query

  1. #function score 查询
  2. GET /hotel/_search
  3. {
  4. "query": {
  5. "function_score": {
  6. "query": {
  7. "match": {
  8. "all": "外滩"
  9. }
  10. },
  11. "functions": [
  12. {
  13. "filter":{
  14. "term":{
  15. "brand":"7天酒店"
  16. }
  17. },
  18. "weight":10
  19. }
  20. ],
  21. "boost_mode":"sum"
  22. }
  23. }
  24. }
  25. }
  26. }

 

复合查询 Boolean Query

 

  1. GET /hotel/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "name": "如家"
  9. }
  10. }
  11. ],
  12. "must_not": [
  13. {
  14. "range": {
  15. "price": {
  16. "gt": 400
  17. }
  18. }
  19. }
  20. ],
  21. "filter": [
  22. {
  23. "geo_distance": {
  24. "distance": "10km",
  25. "location": {
  26. "lat": 31.21,
  27. "lon": 121.5
  28. }
  29. }
  30. }
  31. ]
  32. }
  33. }
  34. }

 搜索结果处理

排序

  1. #sort排序
  2. GET /hotel/_search
  3. {
  4. "query": {
  5. "match_all": {}
  6. },
  7. "sort": [
  8. {
  9. "score": "desc"
  10. },
  11. {
  12. "price": "asc"
  13. }
  14. ]
  15. }
  16. #找到121.612231.034周围的酒店,距离升序排序
  17. GET /hotel/_search
  18. {
  19. "query": {
  20. "match_all": {}
  21. },
  22. "sort": [
  23. {
  24. "_geo_distance": {
  25. "location": {
  26. "lat": 31.034,
  27. "lon": 121.6122
  28. },
  29. "order": "asc",
  30. "unit": "km"
  31. }
  32. }
  33. ]
  34. }

分页

深度分页问题

 

高亮 

 

  1. #分页查询
  2. GET /hotel/_search
  3. {
  4. "query": {
  5. "match_all": {}
  6. },
  7. "sort": [
  8. {
  9. "price": "asc"
  10. }
  11. ],
  12. "from":10,
  13. "size":10
  14. }
  15. #高亮显示 默认情况,ES搜索字段必须与高亮字段一致
  16. GET /hotel/_search
  17. {
  18. "query": {
  19. "match": {
  20. "all": "如家"
  21. }
  22. },
  23. "highlight": {
  24. "fields": {
  25. "name":{
  26. "require_field_match": "false"
  27. }
  28. }
  29. }
  30. }

RestClient查询文档

 

 

 

 

全文检索查询

 

精确查询 

符合查询

排序和分页

 ​​​​​​​高亮

 ​​​​​​​

觉得好的小伙伴记得一键三连哦

  1. public class HotelIsearchTest {
  2. private RestHighLevelClient client;
  3. @Test
  4. void testMatchAll() throws IOException {
  5. //1 准备Request
  6. SearchRequest request = new SearchRequest("hotel");
  7. //2.准备DSL
  8. request.source()
  9. .query(QueryBuilders.matchAllQuery());
  10. //3.发送请求
  11. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  12. //4解析响应
  13. handleRequest(response);
  14. }
  15. /**
  16. * 全文检索查询
  17. * @throws IOException
  18. */
  19. @Test
  20. void testMatch() throws IOException {
  21. //1 准备Request
  22. SearchRequest request = new SearchRequest("hotel");
  23. //2.准备DSL
  24. request.source()
  25. .query(QueryBuilders.matchQuery("all","如家"));
  26. //3.发送请求
  27. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  28. handleRequest(response);
  29. }
  30. /**
  31. * 精确查询、复合查询
  32. * @throws IOException
  33. */
  34. @Test
  35. void testBool() throws IOException {
  36. //1 准备Request
  37. SearchRequest request = new SearchRequest("hotel");
  38. //2.准备DSL
  39. //2.1准备BooleanQuery
  40. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  41. //2.2添加term
  42. boolQuery.must(QueryBuilders.termQuery("city","上海"));
  43. //2.3添加range
  44. boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
  45. request.source()
  46. .query(boolQuery);
  47. //3.发送请求
  48. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  49. handleRequest(response);
  50. }
  51. /**
  52. * 排序和分页
  53. * @throws IOException
  54. */
  55. @Test
  56. void testPageAndSort() throws IOException {
  57. //页码、每页大小
  58. int page = 2,size = 5;
  59. //1 准备Request
  60. SearchRequest request = new SearchRequest("hotel");
  61. //2.准备DSL
  62. //2.1query
  63. request.source()
  64. .query(QueryBuilders.matchAllQuery());
  65. //2.2排序sort
  66. request.source().sort("price", SortOrder.ASC);
  67. //2.3分页from、size
  68. request.source().from((page-1) * size).size(5);
  69. //3.发送请求
  70. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  71. handleRequest(response);
  72. }
  73. /**
  74. * 高亮
  75. * @throws IOException
  76. */
  77. @Test
  78. void testHighlight() throws IOException {
  79. //1 准备Request
  80. SearchRequest request = new SearchRequest("hotel");
  81. //2.准备DSL
  82. //2.1query
  83. request.source()
  84. .query(QueryBuilders.matchQuery("all","如家"));
  85. //2.2高亮
  86. request.source()
  87. .highlighter(
  88. new HighlightBuilder()
  89. .field("name")
  90. .requireFieldMatch(false)
  91. );
  92. //3.发送请求
  93. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  94. handleHighlight(response);
  95. }
  96. private void handleRequest(SearchResponse response) {
  97. //4解析响应
  98. SearchHits searchHits = response.getHits();
  99. //4.1 获取总条数
  100. long total = searchHits.getTotalHits().value;
  101. System.out.println("共搜索到" + total + "条数据");
  102. //4.2文档数组
  103. SearchHit[] hits = searchHits.getHits();
  104. //4.3遍历
  105. for ( SearchHit hit : hits ) {
  106. //获取文档source
  107. String json = hit.getSourceAsString();
  108. //反序列化
  109. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
  110. System.out.println("hotelDoc = " + hotelDoc);
  111. }
  112. System.out.println(response);
  113. }
  114. /**
  115. * 高亮结果分析
  116. * @param response
  117. */
  118. private void handleHighlight(SearchResponse response) {
  119. //4解析响应
  120. SearchHits searchHits = response.getHits();
  121. //4.1 获取总条数
  122. long total = searchHits.getTotalHits().value;
  123. System.out.println("共搜索到" + total + "条数据");
  124. //4.2文档数组
  125. SearchHit[] hits = searchHits.getHits();
  126. //4.3遍历
  127. for ( SearchHit hit : hits ) {
  128. //获取文档source
  129. String json = hit.getSourceAsString();
  130. //反序列化
  131. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
  132. //获取高亮结果
  133. Map<String, HighlightField> highlightFields = hit.getHighlightFields();
  134. if ( !CollectionUtils.isEmpty(highlightFields) ) {
  135. //根据字段名获取如果
  136. HighlightField highlightField = highlightFields.get("name");
  137. if ( highlightField!=null ) {
  138. //获取高亮的值
  139. String name = highlightField.getFragments()[0].string();
  140. //覆盖非高亮结果
  141. hotelDoc.setName(name);
  142. }
  143. }
  144. System.out.println("hotelDoc = " + hotelDoc);
  145. }
  146. System.out.println(response);
  147. }
  148. /**
  149. * 高亮结果解析
  150. */
  151. @BeforeEach
  152. void setUp(){
  153. this.client = new RestHighLevelClient(
  154. RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")
  155. ));
  156. }
  157. @AfterEach
  158. void tearDown()throws IOException{
  159. this.client.close();
  160. }
  161. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/571350
推荐阅读
相关标签
  

闽ICP备14008679号