ElasticSearch概述
ElasticSearch,简称es,es是一个开源的高拓展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身拓展性很好,它可以拓展到上百台服务器,处理PB级别的数据。es也使用java开发并使用Lucene的复杂性,从而让全文检索变得简单 据国际权威的数据库产品评测机构DB Engines的统计,2016年1月,ElasticSearch已超过solr等成为排名第一的搜索引擎类应用
ElasticSearch和solr的差别
ElasticSearch简介
ElasticSearch是一个实时分布式搜索和分析引擎,它让你以前所未有的速度处理大数据的可能 它用于全文搜索,结构化搜索,分析以及这三者混合使用 ElasticSearch是一个基于Apache Lucene?的开源搜索引擎。无论是在开源还是专有邻域,Lucene可以被认为是迄今为止最先进、性能最好的,功能最全的搜索引擎库。 但是。Lucene只是一个库。想要使用它,你必须使用java作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要更深入的了解检索的相关知识来理解它是如何工作的。 ElasticSearch也使用java开发并使用Lucene作为其核心来实现所有索引和功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文检索变得简单
Solr简介
Solr是Apache下的顶级开源项目,采用java开发,它是基于Lucene的全文检索服务器。solr提供优化比Lucene跟为丰富的查询语言,同时实现了可配置、可拓展,并对索引、搜索性能进行了优化 solr可以独立运行,运行在jetty、tomcat等这些servlet容器中,Sole索引的实现方法很简单,用post方法向solr服务器发送一条可描述Filed及其内容的XML文档,Solr根据xml文档的添加、删除、更新索引、Solr搜索只需要发送HTTP GET请求,然后对solr返回xml、json等格式的查询结果进行解析,组织页面布局、solr不提供构建UI的功能,solr提供了一个管理界面,通过管理界面可以对查询的solr的配置和运行情况 Solr是一个开源搜索平台,用于构建搜索应用程序。 是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口 它建立在Lucene(全文搜索引擎)之上。 Solr是企业级的,快速的和高度可扩展的。
Lucene简介
Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能的一个开源框架。Lucene 目前是 Apache Jakarta 家族中的一个开源项目。也是目前最为流行的基于 Java 开源全文检索工具包。
目前已经有很多应用程序的搜索功能是基于 Lucene 的,比如 Eclipse 的帮助系统的搜索功能。Lucene 能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化的文本的,Lucene 就能对你的文档进行索引和搜索。比如你要对一些 HTML 文档,PDF 文档进行索引的话你就首先需要把 HTML 文档和 PDF 文档转化成文本格式的,然后将转化后的内容交给 Lucene 进行索引,然后把创建好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。不指定要索引的文档的格式也使 Lucene 能够几乎适用于所有的搜索应用程序。
ElasticSearch与solr比较
ElasticSearch vs solr 总结
- es基本就是开箱使用,非常简单,Solr安装比较复杂一点
- Solr支持更多格式的数据,比如json,xml,csv,而ElasticSearch仅支持json文件格式
- Solr利用Zookeeper进行分布式管理,而ElasticSearch自身带有分布式协调管理功能。
- Solr官方提供的功能更多,而ElasticSearch本身更注重与核心功能,高级功能多有第三方插件提供,例如图形化页面需要kibana友好支撑
- Solr查询快,但更新索引满,用于电商等查询多的应用
- ElasticSearch建立索引快(查询慢),实时性查询快,用于facebook新浪等搜索
- Solr是传统搜索应用的有力解决方案,但ElasticSearch更适用新兴的实时搜索应用
- Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而ElasticSearch相对开发维护者较少,更新太快,学习使用成本较高
ElasticSearch安装
声明:JDK1.8,最低要求,ElasticSearch客户端,界面工具 java开发,ElasticSearch的版本和我们之后对应的java的核心jar包!版本对应,JDK环境是正常
下载 https://www.elastic.co/cn/ 华为云的镜像去下载 ElasticSearch: https://mirrors.huaweicloud.com/elasticsearch/?C=N&O=D logstash: https://mirrors.huaweicloud.com/logstash/?C=N&O=D kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D
链接: https://pan.baidu.com/s/1xhpIqT8Tm-jN_h2ir9xlwA 提取码: jv4h
-
下载后解压 -
目录介绍 bin 启动文件config 配置文件 log4j2 日志配置文件 jvm.options java虚拟机相关配置 elasticsearch.yml elasticsearch的配置文件 默认9200端口! 跨域!lib 相关jar包modules 功能目录plugins 插件
-
双击bin/elasticsearch.bat文件 -
访问http://127.0.0.1:9200 -
安装可视化界面 ElasticSearch head 下载:https://github.com/mobz/elasticsearch-head -
报错:跨域问题 解决: 打开elasticsearch.yml文件进行配置
http.cors.enabled: true
http.cors.allow-origin: "*"
-
重新启动elasticSearch和elasticsearch-head 索引:相当于一个数据库 新建一个索引 安装kibana
了解ELK
ELK是elasticSearch、Logstash、kibana三大开源框架首字母大写的简称。市面上也被称为Elastic Stack。其中elasticSearch是一个基于Lucene、分布式、通过RESTful方式进行交互的近实时搜索平台框架。像类似于百度、谷歌这种大数据全文搜索引擎的场景都可以使用elasticSearch作为底层支持框架、可见elasticSearch提供的搜索能力确实强大,elasticSearch也被市面上简称为es。 Logstash是ELK的中央数据引流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出带不同的目的地(文件/MQ/redis/elasticSearch/kafka)等。kibana可以将elasticSearch的数据通过友好的页面展示出来,提供实时分析的功能
下载地址:https://www.elastic.co/cn/downloads/kibana 注意:es版本和kibana版本尽量保持一致
下载完解压 启动测试:bin/kibana.bat 端口:5601 访问:http://localhost:5601 英文看不懂咋办?使用汉化插件
打开/config/kibana.yml文件 设置i18n.locale: “zh-CN”
重新启动kibana
Docker安装elasticsearch和kibana
(1)下载ealastic search和kibana
docker pull elasticsearch:7.6.2
docker pull kibana:7.6.2
(2)配置
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
echo "http.host: 0.0.0.0" >/mydata/elasticsearch/config/elasticsearch.yml
chmod -R 777 /mydata/elasticsearch/
(3)启动Elastic search
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.6.2
设置开机启动elasticsearch
docker update elasticsearch --restart=always
(4)启动kibana:
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://39.102.39.109 :9200 -p 5601:5601 -d kibana:7.6.2
设置开机启动kibana
docker update kibana --restart=always
(5)测试
查看elasticsearch版本信息: http://#:9200/
{
"name": "0adeb7852e00",
"cluster_name": "elasticsearch",
"cluster_uuid": "9gglpP0HTfyOTRAaSe2rIg",
"version": {
"number": "7.6.2",
"build_flavor": "default",
"build_type": "docker",
"build_hash": "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date": "2020-03-26T06:34:37.794943Z",
"build_snapshot": false,
"lucene_version": "8.4.0",
"minimum_wire_compatibility_version": "6.8.0",
"minimum_index_compatibility_version": "6.0.0-beta1"
},
"tagline": "You Know, for Search"
}
显示elasticsearch 节点信息http://#:9200/_cat/nodes ,
127.0.0.1 76 95 1 0.26 1.40 1.22 dilm * 0adeb7852e00
访问Kibana: http://#:5601/app/kibana
ES核心概念
1、索引 2、字段类型(mapping) 3、文档(documents)
概述 elasticsearch是面向文档,关系型数据库和elasticsearch客观的对比 集群,节点所以,类型,文档,分片,映射是什么?
Relational DB | elasticsearch |
---|
数据库(database) | 索引(indices) | 表(tables) | type | 行(rows) | documents | 字段(colums) | fieds |
elasticsearch(集群)中可以包含多个索引(数据库),每个索引可以包含多个类型(表),每个类型可以包含多个文档(行),每个文档中有保安多个字段(列)。
物理设计: elasticsearch在后台吧每个索引划分成多个分片,每分分片可以在集群中的不同服务器间迁移
逻辑设计: 一个索引类型中,包含多个文档,比如说文档1,文档2。当我们索引一篇文档时,可以通过这样的一个顺序找到它:索引>类型>文档id>,通过这个组合我们就能索引带某个具体的文档。注意:ID不必是整数,实际上是一个字符串
文档
之前说 elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档, elasticsearch中,文档有几个重要属性:
- 自我包含,一文档同时包含字段和对应的值,也就是同时包含 key: value!name: guangshen
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
- 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在 elasticsearch中,对于字
段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。
类型
类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义称为映射,比如name映射为字符串类型。我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,那么 elasticsearch是怎么做的呢? elasticsearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型, elasticsearch就开始猜,如果这个值是18,那elasticsearch会认为它是整形。但是 elasticsearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关系 型数据库殊途同归了,先定义好字段,然后再使用,别整什么蛾子。
索引
就是数据库! 索引是映射类型的容器, elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了。我们来研究下分片是如何工作的
物理设计:节点和分片如何工作 一个集群至少有一个节点,而一个节点就是一个 elasricsearch进程,节点可以有多个索引默认的,如果你创建索引,那么索引将会 有个5个分片( primary shard,又称主分片)构成的,毎一个主分片会有一个副本( replica shard,又称复制分片) 上图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不于丢失。 实际上,一个分片是一个 Lucene索引,一个包含倒排索引的文件目录,倒排素引的结构使得 elasticsearchi在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。不过,等等,倒排索引是什么鬼?
倒排索引
elasticsearch使用的是一种称为倒排索引的结构,采用 lucene倒排索作为底层。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。例如,现在有两个文档,每个文档包含如下内容
Study every day , good good up to forever # 文档1包含的内容
To forever , Study every day, good good up # 文档2包含的内容
为了创建倒排索引,我们首先要将每个文档拆分成独立的词或称为词条或者 tokens),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档
term | doc_1 | doc_2 |
---|
Study | ? | ? | To | ? | ? | ever | ? | ? | forever | ? | ? | day | ? | ? | study | ? | ? | good | ? | ? | every | ? | ? | to | ? | ? | up | ? | ? |
来看一个示例,比如我们通过博客标签来搜索博客文章。那么倒排索引列表就是这样的一个结构 如果要搜索含有 python标签的文章,那相对于査找所有原始数据而言,查找倒排索引后的数据将会快的多。只需要查看标签这栏,然后获取相关的文章ID即可。完全过滤掉无关的所有数据,提高效率!
elasticsearche的索引和 Lucene的索引对比
在 elasticsearcht中,索引这个词被频繁使用,这就是术语的使用。在 elasticsearch中,索引被分为多个分片,每份分片是一个 Lucene的索引。所以一个 elasticsearch素引是由多个 Lucene索引组成的。别问为什么,谁让 elasticsearch使用 Lucene作为底层呢! 如无特指,说起索引都是指 elasticsearchi的索引 接下来的一切操作都在 kibana中 Dev Tools下的 Consale里完成。 基础操作
IK分词器插件
什么是IK分词器
分词:即把一段中文或者別的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,比如“我爱jd”会被分为我”,”爱”,”j”,”d”,这显 然是不符合要求的,所以我们需要安装中文分词器K来解决这个问题。
如果要使用中文,建议使用ik分词器 IK提供了两个分词算法: ik smart和 ik max word,其中 ik smart为最少切分, ik max word为最细粒度划分!一会我们测试!
安装
下载地址:https://github.com/medcl/elasticsearch-analysis-ik 下载完毕之后,放入到我们的 elasticsearch插件即可! 通过命令查看插件是否加载:elasticsearch-plugin list
使用kibana测试 查看不同分词器的效果 其中 ik smart为最少切分
ik_max_word为细粒度拆分 自定义词典
-
在IK分词器config目录下新建一个*.dic文件 编写自己的词汇 配置到IKAnalyzer.cfg.xml中 重新启动es、kibana Rest风格说明 一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更筒洁,更有层次,更易于实现缓存等机制。
基本Rest命令说明
method | url地址 | 描述 |
---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档d) | POST | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) | POST | locahost:9200/索引名称/类型名称/文档id/_ update | 修改文档 | DELETE | localhost::9200/索引名称/类型名称/文档id | 删除文档 | GET | localhost:9200/索引名称/类型名称文档id | 查询文档通过文档d | POST | localhost::9200/索引名称/类型名称/_search | 查询所有数据 |
索引的基本操作
运行es,kibana、es-head
创建一个索引
PUT /索引名/~类型名~/文档id{ 请求体}
完成了自动増加了索引!数据也成功的添加了 那么name这个字段用不用指定类型呢。毕亮我们关系型数据库是需要指定类型的啊 默认类型:
- 字符串类型:text、keyword
- 数值类型:ling,integer,short,byte,double,float,half float,scaled float
- 日期类型:date
- te布尔值类型:boolean
- 二进制类型:binary
- 等等
指定字段的类型
PUT /test2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
获取索引信息
GET /索引名/~类型名~/文档id
如果自己的文档字段没有指定,那么es就会给我们默认配置字段类型
展:通过命令 elasticsearch索引情況!通过get_cat/可以获得es的当前的很多信息!
修改索引状态
POST /索引名称/类型名称/文档名称/_update
PUT /test3/_doc/1
{
"name":"joker",
"age":18,
"sex":"男"
}
POST /test3/_doc/1/_update
{
"doc":{
"name":"joker_dj"
}
}
删除索引
通过 DELETE命令实现州除、根据你的请求来判断是删除索引还是删除文档记录!
DELETE /索引名称/类型名称/文档名称
删除指定文档
DELETE 索引名称/类型名称/文档id
{
方法体
}
例:
DELETE test3/_doc/1
{
"name":"joker_dj"
}
文档的基本操作
基本操作
创建索引
PUT /joker/user/1
{
"name":"joker_dj",
"age":18,
"desc":"java小萌新",
"tags":["技术宅","直男"]
}
PUT /joker/user/1
{
"name":"joker_dj",
"age":18,
"desc":"java小萌新",
"tags":["技术宅","直男"]
}
PUT /joker/user/3
{
"name":"李四",
"age":5,
"desc":"合伙人",
"tags":["坏人"]
}
获取文档
GET /索引名称/类型名称/文档id
修改文档
重新put一边就是修改 (不推荐) version就是数据被改动的次数 POST _update,推荐使用这种更新方式
POST /索引名称/类型名称/文档id/_update
{
"doc":{
"fieds":"value"
}
}
POST /joker/user/3/_update
{
"doc":{
"name":"张三的哥哥李四"
}
}
文档搜索
简单的搜索
GET /索引名称/[类型名称]/[文档id]
高级搜索 条件查询
GET /索引名称/[类型名称]/_search?q=fieds:value
复杂操作搜索 select(排序,分页,高亮,模糊査询,精准查询!)
根据_score分数进行排序 查看谁最匹配
只要文档中包含value的就会被查出来 前提是被分词器捕获
GET /索引名称/类型名称/_search
{
"query": {
"match": {
"fileds": "value"
}
}
}
GET /joker/user/_search
{
"query": {
"match": {
"name": "张三"
}
}
}
过滤字段
GET /索引名称/类型名称/_search
{
"query": {
"match": {
"fileds": "value"
}
},
"_source": ["fileds","fileds"]
}
GET /joker/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"_source": ["desc","name"]
}
排序
GET /索引名称/类型名称/_search
{
"query": {
"match": {
"fileds": "value"
}
},
"_source": ["fileds","fileds"],
"sort": [
{
"fileds": {
"order": "desc"
}
}
]
}
例:
GET /joker/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"_source": ["desc","name","age"],
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
分页查询
GET /joker/user/_search
{
"query": {
"match": {
"name": "张三"
}
},
"from": 0, # 起始值 page
"size": 20 # 查询大小 pageSize
}
数据下标还是从0开始的,和学的所有数据结构是一样的! /seach/{current}/{pageSize}
布尔查询
多条件查询 must 相当于 and
GET /joker/user/_search
{
"query": {
"bool": {
"must ": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 5
}
}
]
}
}
}
should相当于 or
GET /joker/user/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 5
}
}
]
}
}
}
not操作
GET /joker/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 5
}
}
]
}
}
}
过滤器 filter
GET /joker/user/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "张三"
}
}
],
"filter": {
"range": {
"age": {
"gt": 1,
}
}
}
}
}
}
筛选年龄大于1
- gt 大于
- lt 小于
- gte 大于等于
- lte 小于等于
匹配多个条件
多个条件之间使用空格隔开 只满足其中一个即可查出 通过分值基本判断
精确查询
term查询是直接通过倒排索引指定的词条进程精确的查找的! 关于分词:
- term :直接查询精确的
- match:会使用分词器解析!(先分析文档,然后在通过分析的文档进行查询!)
两个类型 text 、 keyword keyword不会被分词器解析 text 会被分词器解析
多个值匹配的精确查询
高亮查询
GET /joker/user/_search
{
"query": {
"match": {
"name":"张三"
}
},
"highlight": {
"fields": {
"name":{
}
}
}
}
自定义高亮标签
GET /joker/user/_search
{
"query": {
"match": {
"name":"张三"
}
},
"highlight": {
"pre_tags":"<p class='key' style='color:red'>",
"post_tags":"</p>",
"fields": {
"name":{
}
}
}
}
集成SpringBoot
官方文档:
https://www.elastic.co/guide/index.html
查看文档
导入maven pom依赖
1、找到原生的依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
2、初始化 用完后关闭客户端 3、分析类中的方法
- 创建空的父工程
- 创建SpringBoot子模块
勾选相关依赖 下载相关依赖 注意版本问题:要和本地es版本一致,否则可能会出现问题 - 新建配置类
@Configuration
public class ElasticSearchclientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
-
Api测试 创建索引
@SpringBootTest
class ElasticseachApplicationTests {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
@Test
void testCerateIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("joker_index");
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
}
判断索引是否存在
@Test
void testGetindex() throws IOException {
GetIndexRequest request = new GetIndexRequest("joker_index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
删除索引
@Test
void testDeleteindex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("test2");
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
创建添加文档
添加fastjson依赖 方便json转换
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency>
@Test
void testAddDocument() throws IOException {
User user = new User("joker_dj", 18);
IndexRequest request = new IndexRequest("joker_index");
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
request.source(JSON.toJSONString(user), XContentType.JSON);
IndexResponse indexRespons = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexRespons.toString());
System.out.println(indexRespons.status());
}
获取文档 判断文档是否存在
@Test
void testexitdocument() throws IOException {
GetRequest request = new GetRequest("joker_index", "1");
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none_");
boolean exists = client.exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
获取文档的内容
//获取文档的内容 @Test void testGetDocument() throws IOException { GetRequest request = new GetRequest("joker_index", "1"); GetResponse documentFields = client.get(request, RequestOptions.DEFAULT); System.out.println(documentFields.toString());//打印文档的内容 }
更新文档内容
@Test
void testUpdateDocument() throws IOException {
UpdateRequest request = new UpdateRequest("joker_index", "1");
request.timeout("1s");
User user = new User("joker_djs", 20);
request.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
System.out.println(update.status());
}
删除文档记录
@Test
void testDeleteRequst() throws IOException {
DeleteRequest request = new DeleteRequest("joker_index", "1");
request.timeout("1s");
DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
批量插入数据
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> userList=new ArrayList<>();
userList.add(new User("joker1",18));
userList.add(new User("joker2",18));
userList.add(new User("joker3",18));
userList.add(new User("joker4",18));
userList.add(new User("joker5",18));
userList.add(new User("joker6",18));
userList.add(new User("joker7",18));
userList.add(new User("joker8",18));
for (int i = 0; i < userList.size(); i++) {
bulkRequest.add(new IndexRequest("joker_index")
.id(""+(i+1))
.source(JSON.toJSONString(userList.get(i)),XContentType.JSON));
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.hasFailures());
}
高级查询
@Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("joker_index");
SearchSourceBuilder SourceBuilder = new SearchSourceBuilder();
SourceBuilder.highlighter();
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "joker1");
SourceBuilder.query(matchAllQueryBuilder);
SourceBuilder.timeout(new TimeValue(60,TimeUnit.SECONDS));
searchRequest.source(SourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits()));
System.out.println("==============================");
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
|