ElasticSearch搜索详细讲解与操作

这篇具有很好参考价值的文章主要介绍了ElasticSearch搜索详细讲解与操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

全文检索基础

全文检索流程

流程:

创建索引:

查询索引:

相关概念

索引库

索引库就是存储索引的保存在磁盘上的一系列的文件。里面存储了建立好的索引消息以及文档对象。

** 一个索引库相当于数据库中的一张表,一个文档对象相当于数据库中的一行数据

doucument对象

获取原始内容的目的是为了索引,在索引前需要将原始内容建成文档,文档中包含一个一个的域(字段),域中存储内容。每个文档都有一个唯一的编号,就是文档id。

field对象

如果我们把document看作是数据库中的一条记录的话,field相当于是记录中的字段。field是索引库中存储数据的最小单位。field的数据类型大致可以分为数值类型和文本类型,一般需要查询的字段都是文本类型的,field还有如下属性:

是否分词:是否对域的内容进行分词处理。前提是我们对域的内容进行查询

是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到

是否存储:Field值存储在文档中,存储在文档中的Field才可以从Document中获取

term对象

从文档对象中拆分出来的每个单词叫做term,不同域中拆分出来的相同的单词是不同term。term中包含两部分,一部分是文档的域名。另一部分是单词的内容。term是创建索引的关键词对象。

ElasticSearch相关概念

概述

ES是面对文档的,这意味这它可以存储整个对象或文档。然而它不仅仅是存储,还会索引每个文档的内容使之可以被搜索。在ES中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。

ES比较传统关系型数据库如下:

Relational DB -> Databases->Tables->Rows ->Columns

ES->Indices->Types->Documents->Fields

ES核心概念

索引index

一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。

类型type

在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定,通常,会为具有一组共同字段文档定义一个类型。比如说,我们假设你运营一个博客平台

字段Field

相当于是字段表的字段,对文档数据根据不同属性进行的分类标识

映射mapping

mapping是处理数据的范式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其他就是处理es里面的数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。

文档document

一个文档是一个可被索引的基础消息单元。比如,你可以拥有某一个客户的文档,某个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON格式来表示,而JSON是一个到处存在的互联网数据交互格式

在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type

接近实时NRT

ES是一个接近实时的搜索平台,这意味这,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟

集群cluster

集群就是有一个或多个节点组织在一起,它们共同持有整个数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是es。这个名字是重要的,意味一个节点只能通过指定某个集群的名字来加入这个集群

节点node

一个节点是集群的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识,默认情况下,这个名字是一个随机的名字。

分片和复制 shards&replicas

一个索引可以存储超出单个节点硬件限制的大量数据。每个分片本身也是一个功能完善并且独立的索引,这个索引可以被放置到集群的任何节点上。分片很重要,主要有两方面:

1)允许你水平分割/扩展你的内容容量

2)允许你的分片(潜在地,位于多个节点上)之上进行分布式、并行的操作,进而提高性能/吞吐量

要复制的两个原因:在分片/节点失败的情况下,提高了高可用性。因为这个原因,主要到复制分片从不与原/主要分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量。因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片,一个索引也可以被复制0次或多次,一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你是不能改变分片的数量

安装

docker安装

sudo docker pull elasticsearch:5.6.8

启动

sudo docker run -id --name=zys_es -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8

注意:可能因为内存不够或者进程满等原因会中断es进程

安装包安装

sudo apt-get install openjdk-8-jdk #1、安装open-jdk
#2、官网查找需要的es版本 es官网:https://www.elastic.co/cn/downloads/elasticsearch
#点击【apt-get】
#查找自己想要的版本,点击使用deb方式安装
#安装es-7.6.2
1、wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-amd64.deb
2、wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-amd64.deb.sha512
3、shasum -a 512 -c elasticsearch-7.6.2-amd64.deb.sha512 
4、sudo dpkg -i elasticsearch-7.6.2-amd64.deb
#修改配置文件elasticsearch.yml
vi /etc/elasticsearch/elasticsearch.yml

{
node.name: node-1
network.host: 0.0.0.0 #允许外网访问
http.port: 9200 #指定es端口号
clauster.initial_master_nodes: ["node-1"]
}
#修改jvm.options
{
-Xms4g
-Xms4g
}
#启动es
sudo chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/  #目录的owner和group改成elasticsearch
systemctl enable elasticsearch.service    #设置es开机自启动
sudo systemctl start elasticsearch.service    #启动es
sudo systemctl stop elasticsearch.service    #停止es

#查看es运行状态
service elasticsearch status
#查看报错日志
tail -f /var/log/elasticsearch/elasticsearch.log
#检查是否运行正常
curl localhost:9200

# 开启跨域访问支持,默认为false
http.cors.enabled: true
# 跨域访问允许的域名地址
http.cors.allow-origin: "*"
# 通过为 cluster.initial_master_nodes 参数设置符合主节点条件的节点的 IP 地址来引导启动集群
cluster.initial_master_nodes: ["node-1"]

ElasticSearch的客户端操作

三种方式:

第一种:elasticsearch-head操作

第二种:使用elasticsearch提供的Restful接口直接访问

第三种:使用es提供的API直接访问

elasticsearch-head

下载elasticsearch-head安装包
进入目录下打开cmd
npm install -g grunt-cli
启动
npm install
grunt server

Postman

创建索引index和映射Mapping

注意:elasticsearch7默认不在支持指定索引类型,默认索引类型是_doc,如果想改变,则配置include_type_name: true 即可(这个没有测试,官方文档说的,无论是否可行,建议不要这么做,因为elasticsearch8后就不在提供该字段)。官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

7.x之前:

{
    "settings":{    
    "number_of_shards" : 3,   
    "number_of_replicas" : 0    
    },    
     "mappings":{    
      "books":{     //指定索引
        "properties":{        
            "title":{"type":"text"},
            "name":{"type":"text","index":false}, //有index
            "publish_date":{"type":"date","index":false},           
            "price":{"type":"double"},           
            "number":{
                "type":"object",
                "dynamic":true
            }
        }
      }
     }
}

7.x之后:

{
  "settings":{
    "number_of_shards":3, #分片数量
    "number_of_replicas":2 #每个分片副本
  },
  "mappings":{
  //无索引
    "properties":{
      "id":{"type":"long"},
      "name":{"type":"text","analyzer":"standard"}, //无指定index为true或为false,standard为分词器的一种,standard一个汉字一个词
      "text":{"type":"text","analyzer":"ik_max_word"}
    }
  }
 
}

创建索引后设置Mapping

http://120.78.130.50:9200/blog7/hello/mapping

{
    "properties":{
      "id":{"type":"long"},
      "name":{"type":"text","analyzer":"ik_smart"}, //无指定index为true或为false
      "text":{"type":"text","analyzer":"ik_max_word"}
    }
 
}

创建文档document

请求url:

post http://120.78.130.50:9200/blog1/_doc/1

请求体:

{
    "id":1,
    "name":"es是一个lucene的搜索服务器", 
    "text":"阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"
}

修改文档

请求url:

post http://120.78.130.50:9200/blog1/_doc/1

请求体:

{
    "id":1,
    "name":"es是一个lucene的搜索服务器反对犯得上", 
    "text":"阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"
}

文档删除document

delete http://120.78.130.50:9200/blog1/_doc/1

根据id查询文档

GET http://120.78.130.50:9200/blog1/_doc/2

结果

{
    "_index": "blog1", //索引名称
    "_type": "_doc", //索引类型
    "_id": "2", 
    "_version": 1,
    "_seq_no": 2,
    "_primary_term": 1,
    "found": true,
    "_source": { //数据
        "id": 1,
        "name": "es是一个lucene的搜索服务器", //无指定index为true或为false
        "text": "阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"
    }
}

查询文档-querystring查询

url:

POST http://120.78.130.50:9200/blog1/_doc/_search

请求体:

{
    "query": {
        "query_string": {
            "default_field": "name",
            "query": "搜索服务器"
        }
    }
}

钢索->“钢”,“索”,搜索是分为两个词,注意Standard标准分词器,会把汉字每个字分为一个词存到索引库中的name,也就是按照Standard进行的分词,所以搜索钢索能搜到这个document

查询文档-term查询

url:

POST http://120.78.130.50:9200/blog1/_doc/_search

body

{
    "query": {
        "term": {
            "name": "搜索"
        }
    }
}

query_string :搜索之前对搜索的关键词分词

term:对搜索的关键词不分词

IK分词器

安装

下载安装包 :https://github.com/medcl/elasticsearch-analysis-ik/releases

放到/ usr/share/elasticsearch/plugins

重启es

7.x之前测试:

http://120.78.130.50:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员

http://120.78.130.50:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程序员

7.x之后测试:url+body

http://120.78.130.50:9200/_analyze

{

“analyzer”: “ik_smart”,

“text”: “我是傻逼”

}

注意:

​ ik_smart:会做最粗粒度的拆分

​ ik_max_word: 会将文本做最细粒度的拆分

注意出错:将ik解压成功后es可能就启动不了,可能是ik中所有文件的用户组和所有者属于root,需要改成当前的用户组和所有者,用

sudo chmod zys_ergou ./ik/*

sudo chown zys_ergou ./ik/*

还有一种情况就是es和ik的版本不兼容,需要进入plugin-descriptor.properties文件更改es的version

Kibaba

安装

第一步:去官网下载Linux版本的Kibana

https://www.elastic.co/cn/downloads/past-releases#kibana

sudo wget https://artifacts.elastic.co/downloads/kibana/kibana-7.6.2-linux-x86_64.tar.gz

第二步:上传到Linux服务器(可能导致文件不完整,最好用wget下载)

第三步:解压该Kibana压缩包。

sudo tar -zxvf kibana-7.6.2-linux-x86_64.tar.gz //注意文件名称

第四步:去kibana目录下的config/kibana.yml配置相关参数。

  1. server.port: 5601
  2. server.host: “0.0.0.0”
  3. i18n.locale: “zh-CN”

第五步:启动Kibana。进入bin目录下

  1. #root账号启动
  2. ./kibana --allow-root
  3. #root账号后台启动
  4. nohup ./kibana --allow-root &
  5. #其他账号启动
  6. ./kibana
  7. #其他账号后台启动
  8. nohup ./kibana &

第六步:访问Kibana

http://192.168.120.157:5601/

第七步:访问Elasticsearch地址

快捷键:

ctrl + i 自动缩进

ctrl + enter 提交请求

down 打开自动补全菜单

enter 或tab 选中项自动补全

esc 关闭补全菜单

DSL语句使用

SQL查询语句

操作

(1)查询所有索引

GET /_cat/indices?v

(2)删除某个索引

DELETE /blog

(3)新增索引

PUT /user

(4)创建映射

注意:如果不设置include_type_name=true,就会报错"Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true."

PUT /user/uesrinfo/_mapping?include_type_name=true
{
  "properties": {
    "name":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart"
    },
    "city":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart"
    },
    "age":{
      "type": "long"
    },
    "description":{
      "type": "text",
      "analyzer": "ik_smart",
      "search_analyzer": "ik_smart"
    }
  }
}

(5)新增文档数据

PUT /user/_doc/{id}
{
  "name":"王五",
  "age":21,
  "city":"广州",
  "description":"王五来自湖北武汉"
}

(6)替换操作

PUT /user/_doc/3
{
  "name":"王五",
  "age":21,
  "city":"广州",
  "description":"王五来自湖北武汉"
}

(7)根据id查询

GET /user/_doc/2

(8)查询所有

GET /user/_search

(9)Sort排序

GET /user/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

(10)分页

GET /user/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0, 
  "size": 2
}

(11)term查询

term主要用于分词精确匹配,如字符串、数值、日期等(不适合情况:1、列中除英文字符外有其他值2、字符串值中有冒号或中文3、系统自带属性如_version)

GET _search
{
  "query": {
    "term": {//term不分词
      "city": "深圳武汉"
      }
    }
  }
}

GET _search
{
  "query": {
    "match": {//match分词
      "city": "深圳武汉"
    }
  }
}

(12)terms查询

terms查询允许指定多个匹配条件。如果某个字段指定了多个值,那么文档需要一起做匹配

GET _search
{
  "query": {
    "terms": {
      "city": [
          "武汉",
          "广州"
        ]
    }
  }
}

(13)query_string查询

GET _search
{
  "query": {
    "query_string": {
      "default_field": "city",
      "query": "广州武汉"
    }
  }
}

(14)range查询

GET _search
{
  "query": {
    "range": {
      "age": {
        "gte": 20,
        "lte": 22
      }
    }
  }
}

(15)exists

exists过滤可以用于查找拥有某个域的数据

GET _search
{
  "query": {
    "exists": {
      "field": "address"
    }
  }
}

(16)bool查询

bool可以用来合并多个条件查询结果的布尔逻辑,它包含以下操作符:

must:多个查询条件的完全匹配,相当于and

must_not:多个查询条件的相反匹配,相当于not

should:至少有一个查询条件匹配,相当于or

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:

GET _search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "city": {
              "value": "广州"
            }
          }
        },
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 22
            }
          }
        }
      ]
    }
  }
}

(17)match_all查询

可以查询到所有文档,是没有查询条件下的默认句

GET /user/_search
{
  "query": {
    "match_all": {}
  }
}

(18)match查询

match查询是一个标准查询,不管你需要全文查询还是精确查询基本上都要用到它。如果你使用match查询一个全文本字段,它会在真正查询之前用飞行器先分析match一下查询字符:

GET _search
{
  "query": {
    "match": {
      "city": "广州"
    }
  }
}

(19)prefix查询

以什么字符开头的,可以更简单地用prefix,例如查询所有以张开始的用户描述

GET _search
{
  "query": {
    "prefix": {
      "name": {
        "value": "王"
      }
    }
  }
}

(20)multi_match

multi_match查询允许你做match查询的基础上同时搜索多个字段,在多个字段中同时查一个

GET _search
{
  "query": {
    "multi_match": {
      "query": "深圳",
      "fields": [
        "city",
        "description"]
    }
  }
}

ElasticSearch编程操作

添加依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zys</groupId>
    <artifactId>es_demon</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>7.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.6.2</version>
        </dependency>
    </dependencies>
</project>

创建索引

 		//1、配置
Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
        //2、客户端
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(new TransportAddress(InetAddress.getByName("120.78.130.50"), 9300));
        //3、使用api创建索引
        client.admin().indices().prepareCreate("index_hello").get();
        //4、关闭client
        client.close();

添加映射

 //1、配置
        Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
        //2、客户端
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(new TransportAddress(InetAddress.getByName("120.78.130.50"), 9300));

        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject("article")
                        .startObject("properties")
                                .startObject("id")
                                .field("type", "long")
                            .endObject()
                                .startObject("title")
                                .field("type", "text")
                                .field("analyzer", "ik_smart")
                            .endObject()
                                .startObject("content")
                                .field("type", "text")
                                .field("analyzer", "ik_smart")
                            .endObject()
                        .endObject()
                    .endObject()
                .endObject();
        //3、使用api创建索引
        client.admin().indices().preparePutMapping("index_hello").setType("article").setSource(xContentBuilder).get();
        //4、关闭client
        client.close();

创建文档

1、使用XContenBuilder构建Document对象

XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", 2l)
                .field("title", "少大金欧涉及到山东哈收到拉萨DHL撒鲁大师鲁大师劳动力")
                .field("content", "啥的拉升阶段拉萨伦敦苏富比老大就是领导破碎了就爱上了大家来打死你电脑来合肥把程序内存,整理骄傲我觉得阿拉善的距离撒娇的了就")
                .endObject();
        client.prepareIndex()
                //设置索引名称
                .setIndex("index_hello")
                //设置type
                .setType("article")
                //设置文档的id,如果不设置的话自动生成一个id
                .setId("1")
                //设置文档信息
                .setSource(builder)
                //执行操作
                .get();

2、实体对象

依赖:

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.1</version>
        </dependency>

实体类:

	private Integer id;
    private String title;
    private String content;

添加:

 Article article = new Article();
        article.setId(3l);
        article.setTitle("撒娇多久啊老师的就爱上了你发到你爱丽丝的你拉车的你");
        article.setContent("jdaosdnasdnlddawhlcncsnskndaskndasldnslnslkdsal;dasmd;");
   ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(article);
        client.prepareIndex()
                .setIndex("index_hello")
                .setType("article")
                .setSource(objectMapper, XContentType.JSON)
                .get();


    }

查询文档

TermQuery

 //创建QueryBuilder对象
//        QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "你");//term查询
        QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("你的宝贝").defaultField("title");//match查询
//        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "你的宝贝");//match查询
//        IdsQueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("3", "4");//根据id查询
        
        //执行查询得到一个结果
        SearchResponse searchResponse = client.prepareSearch("index_hello")
                .setTypes("article")
                .setQuery(queryBuilder)
                .get();
        //处理结果
        SearchHits hits = searchResponse.getHits();
        System.out.println("总行数" + hits.getTotalHits());
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit next = iterator.next();
            //文档的json输入
            System.out.println(next.getSourceAsString());
        }

分页查询

//创建QueryBuilder对象
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "你的宝贝");//match查询

        //执行查询得到一个结果
        SearchResponse searchResponse = client.prepareSearch("index_hello")
                .setTypes("article")
                .setQuery(queryBuilder)
                .setFrom(0)///
                .setSize(5)///
                .get();
        //处理结果
        SearchHits hits = searchResponse.getHits();
        System.out.println("总行数" + hits.getTotalHits());
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit next = iterator.next();
            //文档的json输入
            System.out.println(next.getSourceAsString());
        }

查询结果高亮显示

       MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("少啥", "title", "content");//multi_match查询
//
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<em>");
        highlightBuilder.preTags("</em>");
/
        //执行查询得到一个结果
        SearchResponse searchResponse = client.prepareSearch("index_hello")
                .setTypes("article")
                .setQuery(queryBuilder)
                .highlighter(highlightBuilder)//
                .get();
        //处理结果
        SearchHits hits = searchResponse.getHits();
        System.out.println("总行数" + hits.getTotalHits());
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit next = iterator.next();
            //文档的json输入
            System.out.println(next.getSourceAsString());
            System.out.println("==============highlight==============");
            Map<String, HighlightField> highlightFieldMap = next.getHighlightFields();
            for (Map.Entry<String, HighlightField> entry : highlightFieldMap.entrySet()) {
                System.out.println(entry.getKey() + "\t" + Arrays.toString( entry.getValue().getFragments()));
            }
        }

Spring Data ElasticSearch

1、搭建spring boot项目

Spring Data Release Train Spring Data Elasticsearch Elasticsearch Spring Framework Spring Boot
2022.0 (Turing) 5.0.x 8.5.0 6.0.x 3.0.x
2021.2 (Raj) 4.4.x 7.17.3 5.3.x 2.7.x
2021.1 (Q) 4.3.x 7.15.2 5.3.x 2.6.x
2021.0 (Pascal) 4.2.x[1] 7.12.0 5.3.x 2.5.x
2020.0 (Ockham)[1] 4.1.x[1] 7.9.3 5.3.2 2.4.x
Neumann[1] 4.0.x[1] 7.6.2 5.2.12 2.3.x
Moore[1] 3.2.x[1] 6.8.12 5.2.12 2.2.x
Lovelace[1] 3.1.x[1] 6.2.2 5.1.19 2.1.x
Kay[1] 3.0.x[1] 5.5.0 5.0.13 2.0.x
Ingalls[1] 2.1.x[1] 2.4.0 4.3.25 1.5.x

2、编写yml文件

spring:
  elasticsearch:
    rest:
      uris: 120.78.130.50:9300

3、编写实体类

//type在2.3.x版本不写即可,实体类名字即是type
@Document(indexName = "zys_blog", type = "article")
public class Article {

    @Id
    @Field(type = FieldType.Long, store = true)
    private Long id;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
    private String title;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
    private String content;
}

4、编写Dao

方法命名规则查询的基本语法findBy+属性+关键词+连接符

关键词:and,or,is,not,between,lessThanEqual

public interface ArticleDao extends ElasticsearchRepository<Article, Long> {
}

5、使用

  @Autowired
	private ElasticsearchRestTemplate template ;

RestHighLevelClient

引入依赖

 <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
private RestHighLevelClient client; 
@Test
    public void createIndex() throws IOException {
        HttpHost httpHost = HttpHost.create("120.78.130.50:9200");
        RestClientBuilder builder = RestClient.builder(httpHost);
        client = new RestHighLevelClient(builder);
        //创建连接
        
        CreateIndexRequest request = new CreateIndexRequest("book_index");
        String json = "{\n" +
                "  \"mappings\": {\n" +
                "    \"properties\": {\n" +
                "      \"id\":{\n" +
                "        \"type\":\"keyword\"\n" +
                "      },\n" +
                "      \"name\":{\n" +
                "        \"type\":\"text\",\n" +
                "        \"analyzer\":\"ik_max_word\"\n" +
                "      },\n" +
                "      \"type\":{\n" +
                "        \"type\":\"keyword\"\n" +
                "      },\n" +
                "      \"description\":{\n" +
                "        \"type\":\"text\",\n" +
                "        \"analyzer\": \"ik_max_word\"\n" +
                "      }\n" +
                "    }\n" +
                "  }\n" +
                "}";
        request.source(json, XContentType.JSON);
        client.indices().create(request, RequestOptions.DEFAULT);//创建索引库
        
        client.close();
    }

添加文档

@Test
    public void addDoc() throws Exception{
        Book book = bookDao.selectById(1);//从数据库中查询一个对象
        IndexRequest request = new IndexRequest("book_index").id(book.getId().toString());
        String json = JSON.toJSONString(book);//对象转为json

        request.source(json, XContentType.JSON);
        client.index(request, RequestOptions.DEFAULT);
    }

//批处理添加文档//
@Test
    public void addallDoc() throws Exception{
        List<Book> bookList = bookDao.selectList(null);//从数据库中查询所有对象

        BulkRequest bulk = new BulkRequest();//创建一个批处理对象
        for (Book book : bookList) {
            IndexRequest request = new IndexRequest("book_index").id(book.getId().toString());
            String json = JSON.toJSONString(book);//对象转为json
            request.source(json, XContentType.JSON);
            bulk.add(request);
        }
        client.bulk(bulk, RequestOptions.DEFAULT);
    }

查询文档

///根据id查询
@Test
    void testQuery() throws IOException {
        GetRequest request = new GetRequest("book_index","1");
        GetResponse res = client.get(request, RequestOptions.DEFAULT);
        String sourceAsString = res.getSourceAsString();
        System.out.println(sourceAsString);
    }

///条件查询/


@Test
    void Query() throws IOException {

        SearchRequest request = new SearchRequest("book_index");
        //设置条件
        SearchSourceBuilder buider = new SearchSourceBuilder();
        buider.query(QueryBuilders.termQuery("name", "java"));
        request.source(buider);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        //处理结果
        SearchHits hits = search.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            JSON.parseObject(sourceAsString, Book.class);//json对为对象
            System.out.println(Book);
        }
    }

聚合查询

划分桶:把不同标题分开

GET /car_index/car/_search
{
  "query": { //查询所有
    "bool": {
      "should": [
        {
          "match_all": {}
        }
      ]
    }
  },
  "aggs": {
    "group_by_bland": { //group_by_bland为桶名字
      "terms": { //
        "field": "color", //把各颜色分开,比如白色为一组(一个容器aggregations),黄色为一组
      }
    }
  }
}

桶内度量文章来源地址https://www.toymoban.com/news/detail-605267.html

GET /car_index/car/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_all": {}
        }
      ]
    }
  },
  "aggs": {
    "group_by_bland": {
      "terms": {
        "field": "color" //分开各颜色
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price" //求各颜色里面的价格平均值
          }
        }
      }
    }
  }
}

到了这里,关于ElasticSearch搜索详细讲解与操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java的Elasticsearch与搜索引擎

    Elasticsearch是一个基于分布式的实时搜索和分析引擎,它是一个开源的搜索引擎,可以用来构建实时、可扩展的搜索应用程序。Elasticsearch是一个基于Lucene的搜索引擎,它提供了一个分布式、可扩展的搜索引擎,可以处理大量数据并提供实时搜索功能。 Java是Elasticsearch的主要编

    2024年02月20日
    浏览(44)
  • 用SpringBoot和ElasticSearch实现网盘搜索引擎,附源码,详细教学

    可以扫描小程序码体验,切换到搜索Tabbar。 小程序端界面实现 网页端实现界面 对外提供的api 接口声明 接口实现 执行搜索策略。 提供2种搜索策略,分别是MySQL和ElasticSearch搜索策略。在配置文件进行配置搜索策略。 搜索类型枚举 配置文件中的搜索策略相关配置 es搜索策略实

    2024年02月08日
    浏览(42)
  • Java远程连接本地开源分布式搜索引擎ElasticSearch

    简单几步,结合Cpolar内网穿透工具实现Java远程连接操作本地Elasticsearch。 什么是elasticsearch?一个开源的分布式搜索引擎,具备非常多强大功能,可以用来实现搜索、日志统计、分析、系统监控等功能,可以帮助我们从海量数据中快速找到需要的内容。 Cpolar内网穿透提供了更高

    2024年02月05日
    浏览(50)
  • ElasticSearch搜索引擎:常用的存储mapping配置项 与 doc_values详细介绍

    ES底层使用 Lucene 存储数据,Lucene 的索引包含以下部分: A Lucene index is made of several components: an inverted index, a bkd tree, a column store (doc values), a document store (stored fields) and term vectors, and these components can communicate thanks to these doc ids. 其中: inverted index:倒排索引。 bkd tree: Block k-d tre

    2024年02月07日
    浏览(35)
  • elasticsearch(ES)分布式搜索引擎01——(初识ES,索引库操作和文档操作,RestClient操作索引库和文档)

    1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 1.1.2.ELK技术栈 elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域: 而elasticsearc

    2024年02月07日
    浏览(62)
  • 如何使用内网穿透工具实现Java远程连接本地Elasticsearch搜索分析引擎

    简单几步,结合Cpolar 内网穿透工具实现Java 远程连接操作本地分布式搜索和数据分析引擎Elasticsearch。 Cpolar内网穿透提供了更高的安全性和隐私保护,通过使用加密通信通道,Cpolar技术可以确保数据传输的安全性,这为用户和团队提供了更可靠的保护,使他们能够放心地处理和

    2024年02月04日
    浏览(53)
  • ES搜索引擎入门+最佳实践(九):项目实战(二)--elasticsearch java api 进行数据增删改查

            本篇是这个系列的最后一篇了,在这之前可以先看看前面的内容: ES搜索引擎入门+最佳实践(一)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(二)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(三)_flame.liu的博客-CSDN博客 ES搜索引擎入门+最佳实践(四)_flame.liu的博客

    2024年02月12日
    浏览(59)
  • 超详细讲解Elasticsearch的基本操作

    📢📢📢📣📣📣 哈喽!大家好 ,我是【 一心同学 】,一位上进心十足的【 Java领域博主】! 😜😜😜 ✨【 一心同学 】的 写作风格 :喜欢用【 通俗易懂 】的文笔去讲解每一个知识点,而不喜欢用【 高大上 】的官方陈述。 ✨【 一心同学 】博客的 领域 是【 面向后端技

    2024年02月03日
    浏览(46)
  • 分布式搜索引擎ElasticSearch——深入elasticSearch

    聚合的分类 DSL实现Bucket聚合 DSL实现Metric聚合 RestAPI实现聚合 https://github.com/medcl/elasticsearch-analysis-pinyin DSL实现自动补全查询 Completion Suggester 修改酒店索引库数据结构 RestAPI实现自动补全查询 实现酒店搜索页面输入框的自动补全 数据同步思路分析 利用MQ实现mysql与elasticsearch数

    2024年01月17日
    浏览(47)
  • 【ElasticSearch】深入了解 ElasticSearch:开源搜索引擎的力量

    在信息时代,数据的增长速度之快让我们迅速感受到了信息爆炸的挑战。在这个背景下,搜索引擎成为了我们处理海量数据的得力工具之一。而 ElasticSearch 作为一款强大的开源搜索引擎,不仅能够高效地存储和检索数据,还在日志分析、实时监控等领域展现了其卓越的性能。

    2024年02月08日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包