ElasticSearch查询笔记目录
涉及的常用查询内容较多,将分多个章节进行笔记整理,具体如下:
主要是依据精准的查询条件来查询,查询速度快,也是最常用的几类查询方式,具体种类如下:
- term查询
- terms查询
- match_all查询
- match查询
- 布尔match查询
- multi_match查询
- 根据文档id查询(单个id)
- 根据文档ids查询(多个id)
主要是涉及ElasticSearch查询条件相对模糊,查询速度相对慢,实时查询时应尽量避免这些方式,但是这些查询方式又具有自己独特不可代替的功能,还是还有必要,具体如下:
- prefix查询
- fuzzy查询
- wildcard查询
- range查询
- regexp查询
主要涉及ElasticSearch的一些常用的杂项查询;
- 深分页scroll查询
- delete-by-query
- bool查询
- boosting查询
- filter查询
- highlight(高亮)查询
主要涉及ES的聚合查询Aggregations;
- cardinality(去重计数)查询
- range(范围统计)查询
- extended_stats(统计聚合)查询
. 主要涉及ES的地图检索geo相关的查询;
- geo_distance查询
- geo_bounding_box查询
- geo_polygon查询
整体Java代码的测试用例项目
整个章节的Java代码放在CSDN资源ElasticSearch常用查询的Java实现;路径效果如下图,欢迎下载访问;
前 言
ElasticSearch(以下简称:ES)作为搜索引擎,那么她最核心的重点当然是查询,接下来就给大家整理下ES的一些常用的搜索实现,本笔记主要实现RESTFul风格的代码和Java API代码为主,至于更多的其它API,可参考官网的各类API来实现;
官网各类编程语言API:Elasticsearch Clients
ElasticSearch的版本
本人使用的ES版本是7.7.1
,已经去除了type
的概念。
ElasticSearch测试的索引及数据准备
索引要求
索引名称:sms-logs-index
字段名称 | 备注 | ES数据类型 |
---|---|---|
createDate | 创建时间 | date |
senDate | 发送时间 | date |
longCode | 发送的长号码,如“102365024” | keyword |
moblie | 手机号码,如“13526544896” | keyword |
corpName | 发送公司名称,需要分词检索 | text(ik分词器) |
smsContent | 发送短信内容,需要分词检索 | text(ik分词器) |
state | 短信下发状态 1 成功 0 失败 | integer |
opratorId | 运营商编号 1移动 2 联通 3电信 | integer |
province | 省份 | keyword |
ipAddr | 下发的服务器地址 | keyword |
replyTotal | 短信状态报告返回时长(秒) | integer |
fee | 扣费 | integer |
这里创建测试索引和添加测试数据我就偷懒以下,就直接用RESTFul代码实现,就不用Java了,如果对Java版本创建索引和添加数据有疑问的,可以参考博客ElasticSearch数据结构和基本操作;
RESTful操作新建索引
PUT /sms-logs-index
{
"settings":
{
"number_of_replicas": 3
, "number_of_shards": 5
}
, "mappings":
{
"properties":
{
"createDate":
{
"type": "date"
,"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
,"senDate":
{
"type": "date"
,"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
,"longCode":
{
"type": "keyword"
}
,"moblie":
{
"type": "keyword"
}
,"corpName":
{
"type": "text"
,"analyzer": "ik_smart"
}
,"smsContent":
{
"type": "text"
,"analyzer": "ik_smart"
}
,"state":
{
"type": "integer"
}
,"opratorId":
{
"type": "integer"
}
,"province":
{
"type": "keyword"
}
,"ipAddr":
{
"type": "keyword"
}
,"replyTotal":
{
"type": "integer"
}
,"fee":
{
"type": "double"
}
}
}
}
RESTful操作添加测试数据
PUT /sms-logs-index/_doc/1
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"10201021"
,"moblie":13026254898
,"corpName":"上海智慧软件有限公司"
,"smsContent":"连接你我,智慧软件,让生活更美好"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"0.1"
}
PUT /sms-logs-index/_doc/2
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"20165411010"
,"moblie":15248754897
,"corpName":"北京鑫鑫能源有限公司"
,"smsContent":"欢迎使用新能源,让世界更环保"
,"state":"1"
,"opratorId":"2"
,"province":"北京"
,"ipAddr":"10.245.29.280"
,"replyTotal":"0.6"
,"fee":"0.5"
}
PUT /sms-logs-index/_doc/3
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"5478434123"
,"moblie":18056587445
,"corpName":"中威集团"
,"smsContent":"中威集团,服务于你的身边!"
,"state":"0"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.248.19.45"
,"replyTotal":"4"
,"fee":"20"
}
PUT /sms-logs-index/_doc/4
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"87454120"
,"moblie":13625789645
,"corpName":"爱美化妆品有限公司"
,"smsContent":"魅力,势不可挡,爱美爱美"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.258.19.45"
,"replyTotal":"1"
,"fee":"200"
}
PUT /sms-logs-index/_doc/5
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"24514635"
,"moblie":18545427895
,"corpName":"东东集团"
,"smsContent":"数据驱动,AI推动,新零售模型让你的购买更心怡!"
,"state":"1"
,"opratorId":"1"
,"province":"北京"
,"ipAddr":"10.254.19.45"
,"replyTotal":"1"
,"fee":"6000"
}
PUT /sms-logs-index/_doc/6
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"89451254"
,"moblie":13028457893
,"corpName":"大兴建筑有限公司"
,"smsContent":"我房建,你放心,大兴建筑!"
,"state":"1"
,"opratorId":"1"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"500"
}
PUT /sms-logs-index/_doc/7
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"33656412674"
,"moblie":18956451203
,"corpName":"华丽网集团"
,"smsContent":"网络安全,华丽靠谱!"
,"state":"1"
,"opratorId":"3"
,"province":"上海"
,"ipAddr":"10.215.254.45"
,"replyTotal":"1"
,"fee":"2000"
}
PUT /sms-logs-index/_doc/8
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"56412345"
,"moblie":17055452369
,"corpName":"万事Ok公司"
,"smsContent":"万事Ok,找我没错!"
,"state":"0"
,"opratorId":"2"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"200"
}
PUT /sms-logs-index/_doc/9
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"5784320"
,"moblie":15236964578
,"corpName":"花花派"
,"smsContent":"花开花落,魅力女性,买花选我!"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.265.19.45"
,"replyTotal":"1"
,"fee":"0.1"
}
PUT /sms-logs-index/_doc/10
{
"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"54784641"
,"moblie":15625584654
,"corpName":"勾股科技有限公司"
,"smsContent":"智能算法,智慧生活,勾股科技!"
,"state":"1"
,"opratorId":"2"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"6"
,"fee":"4000"
}
PUT /sms-logs-index/_doc/11
{
"createDate":"2020-09-22"
,"senDate":"2020-09-22"
,"longCode":"458744536"
,"moblie":134625584654
,"corpName":"星雨文化传媒"
,"smsContent":"魅力宣传,星雨传媒!"
,"state":"1"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.289.19.45"
,"replyTotal":"6"
,"fee":"500"
}
PUT /sms-logs-index/_doc/12
{
"createDate":"2020-09-22"
,"senDate":"2020-09-22"
,"longCode":"123546241"
,"moblie":156625584654
,"corpName":"哈雷天文用具公司"
,"smsContent":"天文研究,放心推动,哈雷天文!"
,"state":"1"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.289.19.45"
,"replyTotal":"6"
,"fee":"500"
}
ElasticSearch常用查询原理及实现
本人采用采用IDE编辑Java代码,用到的maven依赖文件pom.xml
如下;
<?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>org.example</groupId>
<artifactId>SparkOnHiveToEs_v1</artifactId>
<version>1.0-SNAPSHOT</version>
<name>SparkOnHiveToEs_v1</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
<!--ES本身的依赖-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
<!--ES高级API,用来连接ES的Client等操作-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<!--junit,Test测试使用-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<!--lombok ,用来自动生成对象类的构造函数,get,set属性等-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<!--jackson,用来封装json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch-spark-20 -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-spark-20_2.11</artifactId>
<version>7.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.11</artifactId>
<version>2.3.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 在maven项目中既有java又有scala代码时配置 maven-scala-plugin 插件打包时可以将两类代码一起打包 -->
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- maven 打jar包需要插件 -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- 设置false后是去掉 MySpark-1.0-SNAPSHOT-jar-with-dependencies.jar 后的 “-jar-with-dependencies” -->
<!--<appendAssemblyId>false</appendAssemblyId>-->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.bjsxt.scalaspark.core.examples.ExecuteLinuxShell</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
一样的,先实现连接ES的client类和方法;
package cn.focusmedia.esapp.feign;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
@Slf4j
public class EsClient
{
public static RestHighLevelClient getClient()
{
//配置集群连接的IP和端口,正式项目是要走配置文件的,这里偷懒下,就写死吧,也方便说明问题,不要骂我代码太烂就行
//创建HttpHost对象
HttpHost[] myHttpHost = new HttpHost[7];
myHttpHost[0]=new HttpHost("10.219.10.11",9200);
myHttpHost[1]=new HttpHost("10.219.10.12",9200);
myHttpHost[2]=new HttpHost("10.219.10.13",9200);
myHttpHost[3]=new HttpHost("10.219.10.14",9200);
myHttpHost[4]=new HttpHost("10.219.10.15",9200);
myHttpHost[5]=new HttpHost("10.219.10.16",9200);
myHttpHost[6]=new HttpHost("10.219.10.17",9200);
//创建RestClientBuilder对象
RestClientBuilder myRestClientBuilder=RestClient.builder(myHttpHost);
//创建RestHighLevelClient对象
RestHighLevelClient myclient=new RestHighLevelClient(myRestClientBuilder);
log.info("RestClientUtil intfo create rest high level client successful!");
return myclient;
}
}
万事具备,开始正式进入主题,关于ES的常用查询的笔记如下;
注意:第一个查询例子本人会贴图查看RESTFul代码及Java代码的查询结果,详细说明结果字段的含义,后续的查询本人只提供两种API的样例代码,不再贴出查询结果,希望读者自行实验以下,举一反三,至于RESTFul代码和Java代码,都是本人分别在Kibana和IDE上测试实现过的,基本不会有啥bug,如果有不足,请大家留言指出,大家一起探讨下。
term查询
term的查询是代表完全匹配,搜索之前不会对你搜索的关键字进行分词,如关键字手机,不会分成手和机;再根据关键字去文档分词库中去匹配内容。
类似于MySQL库的 where province = ?
实现要求,依据province字段查询所有北京公司的短信内容
RESTFUL代码如下;
# from size类似于musql的limit
POST /sms-logs-index/_search
{
"from": 0
,"size": 10
, "query": {
"term": {
"province": {
"value": "北京"
}
}
}
}
RESTFUL查询结果代码如下图2;
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void termsQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest mySearchRequest = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.from(0).size(10).query(QueryBuilders.termsQuery("province", "北京", "上海", "杭州")); //指定term查新条件
mySearchRequest.source(builder);
//3. 执行查询
SearchResponse search = myClient.search(mySearchRequest, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//注意RESTFUL风格上是两个hits,所以这里要两次getHits()
for (SearchHit hit : search.getHits().getHits()) {
Map<String, Object> result = hit.getSourceAsMap();
System.out.println(result);
}
}
Java代码如下;
terms查询
terms和terms的查询机制是一样的,都不会将指定的查询关键字进行分词,直接去分词库中匹配,找到相应的文档内容。
terms:是针对一个字段包含多个值时使用。
换句话说:
term类似于MySQL的 where province=?
terms类似于MySQL中的 where province in (?, ? ,?)
注意:term和terms只是说不会对关键字进行分词,并不是说只能用于keyword类型的字段查询,如假设文档中有个字段是text类型,采用了ik分词器,里面的值是奋斗的时代
,通过网上在线ik分词器,我们知道会分解成奋斗,奋,斗,时代
,如图4,但是如果你用该字段的term或者terms查询,输入的关键字是奋斗的时代
,因为输入的关键字不会分词,反而查不到该记录,如果你输入的关键字是奋斗
就是可以的。
实现要求,依据province字段查询所有北京,上海,杭州公司的短信内容
RESTFUL代码如下;
# from size类似于musql的limit
POST /sms-logs-index/_search
{
"from": 0
,"size": 20
, "query":
{
"terms": {
"province": [
"北京1",
"上海",
"杭州"
]
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void termsQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest mySearchRequest = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.from(0).size(10).query(QueryBuilders.termsQuery("province", "北京", "上海", "杭州")); //指定term查新条件
mySearchRequest.source(builder);
//3. 执行查询
SearchResponse search = myClient.search(mySearchRequest, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
for (SearchHit hit : search.getHits().getHits()) {
Map<String, Object> result = hit.getSourceAsMap();
System.out.println(result);
}
}
match_all查询
查询全部内容,不指定任何查询条件。
实现要求,查询返回所有的记录。
RESTFUL代码如下;
#match_all查询
POST /sms-logs-index/_search
{
"query": {
"match_all": {
}
}
}
注意:如图5实际有12条数据,只返回了10条,是因为默认查询数据返回的结果比较大时,ES只返回前10条数据,即默认的size=10.如果需要返回更多的结果,可以改写size的大小
#match_all查询
POST /sms-logs-index/_search
{
"from": 0,
"size": 20,
"query": {
"match_all": {
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void matchAllQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest request = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
//虽然matchall没有条件,但是还是要指定查询类型为matchall
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
builder.size(20); //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
request.source(builder);
//3. 执行查询
SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//遍历输出每个文档
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//输出总文档数
System.out.println(response.getHits().getHits().length);
}
match查询
match查询属于高层查询,会根据你查询的字段的类型不一致,采用不同的查询方式。
- 如果查询的是日期或者数值的字段,他会自动将你的字符串查询内容转换成日期或者数值对待;
- 如果查询的内容是一个不能被分词的字段(keyword).match查询不会对你的指定查询关键字进行分词;
- 如果查询的内容是一个可以分词的字段(text),match会将你指定的查询内容根据一定的方式去分词,然后去分词库中匹配指定的内容。
总而言之:match查询,实际底层就是多个term查询,将多个term查询的结果汇集到一起返回给你。
实现要求,依据smsContent字段查询所有包含魅力宣传
的公司的短信内容
RESTFUL代码如下;
# from size类似于musql的limit
#match查询
POST /sms-logs-index/_search
{
"from": 0
, "size": 20
, "query": {
"match": {
"smsContent": "魅力宣传"
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void matchQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest request = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery("smsContent","魅力宣传"));
builder.size(20); //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
request.source(builder);
//3. 执行查询
SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//遍历输出每个文档
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//输出总文档数
System.out.println(response.getHits().getHits().length);
}
布尔match查询
拥有match查询的特性,同时可以基于一个field匹配内容,采用and或者or的方式
实现要求,依据smsContent字段查询所有即包含魅力
也宣传
的公司的短信内容
RESTFUL代码如下;
# from size类似于musql的limit
#布尔match查询,内容即包含魅力,也包含宣传,是个and的关系
POST /sms-logs-index/_search
{
"from": 0,
"size": 20,
"query": {
"match": {
"smsContent":
{
"query": "魅力 宣传"
, "operator": "and"
}
}
}
}
#布尔match查询,内容包含魅力,或者宣传,是个or的关系
POST /sms-logs-index/_search
{
"from": 0,
"size": 20,
"query": {
"match": {
"smsContent":
{
"query": "魅力 宣传"
, "operator": "or"
}
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void booleanMatchQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest request = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery("smsContent","魅力 宣传").operator(Operator.AND)); //根据业务选择AND 或者OR
builder.size(20); //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
request.source(builder);
//3. 执行查询
SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//遍历输出每个文档
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//输出总文档数
System.out.println(response.getHits().getHits().length);
}
multi_match查询
拥有match的特性,multi_match针对多个field进行检索,多个field对应一个查询的关键字;
实现要求,查询包含北京
的字段province
或者字段smsContent
。
RESTFUL代码如下;
# multi_match查询
POST /sms-logs-index/_search
{
"query": {
"multi_match": {
"query": "北京",
"fields": ["province","smsContent"]
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void multiMatchQuery() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest request = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.multiMatchQuery("北京","province","smsContent")); //根据业务选择AND 或者OR
builder.size(20); //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
request.source(builder);
//3. 执行查询
SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//遍历输出每个文档
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//输出总文档数
System.out.println(response.getHits().getHits().length);
}
以上两种最重要的查询term
查询和match
查询就讲到这里,接下来再看看一些其他的常用查询。
根据文档id查询(单个id)
ES每一行数据,即文档都会有一个id,如果指定某一列field值作为id,则该列field必须为唯一键,类似于MySQL的UK;不过不指定,ES会自动生成,常常为了更好的定位数据,会指定一列满足UK的field作为文档的id,接下来我们说一下根据id查询。
类似MySQL的 where id=?
实现要求,查询索引sms-logs-index
文档id等于1的文档。
RESTFUL代码如下;
#根据文档的id查询
GET /sms-logs-index/_doc/1
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void findById() throws IOException {
//1.创建GetRequest
GetRequest getRequest = new GetRequest(index,"1");
//2.执行查询
GetResponse response = myClient.get(getRequest, RequestOptions.DEFAULT);
//3.输出结果
System.out.println(response.getSourceAsMap());
}
s
根据文档ids查询(多个id)
根据多个id查询,类似MySQL中的where id in(id1,id2,id3)
实现要求,查询索引sms-logs-index
文档id为1,2,3的文档。
RESTFUL代码如下;
#ids查询
POST /sms-logs-index/_search
{
"query": {
"ids": {
"values": [1,2,3]
}
}
}
Java代码如下;
static RestHighLevelClient myClient= EsClient.getClient(); //获取操作ES的
String index="sms-logs-index";
@Test
public void findByIds() throws IOException {
//1。创建request对象,查询用的对象一般都是SearchRequest对象
SearchRequest request = new SearchRequest(index);
//2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.idsQuery().addIds("1","2","3"));
builder.size(20); //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
request.source(builder);
//3. 执行查询
SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
//遍历输出每个文档
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//输出总文档数
System.out.println(response.getHits().getHits().length);
}
本文参考链接:https://blog.csdn.net/LXWalaz1s1s/article/details/108704773