[ElasticSearch]Java API之TermQuery

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/52852483 1. 词条查询(Term Query)词条查询是ElasticSearch的一个简单查询。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/52852483

1. 词条查询(Term Query)

词条查询是ElasticSearch的一个简单查询。它仅匹配在给定字段中含有该词条的文档,而且是确切的、未经分析的词条。term 查询 会查找我们设定的准确值。term 查询本身很简单,它接受一个字段名和我们希望查找的值。

下面代码查询将匹配 college 字段中含有"California"一词的文档。记住,词条查询是未经分析的,因此需要提供跟索引文档中的词条完全匹配的词条。请注意,我们使用小写开头的california来搜索,而不是California,因为California一词在建立索引时已经变成了california(默认分词器)。

// Query
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("country", "AWxhOn".toLowerCase());
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(termQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-term-query.html

2. 多词条查询(Terms Query)

词条查询(Term Query)允许匹配单个未经分析的词条,多词条查询(Terms Query)可以用来匹配多个这样的词条。只要指定字段包含任一我们给定的词条,就可以查询到该文档。

下面代码得到所有在 country 字段中含有 “德国” 或 "比利时" 的文档。

// Query
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("country", "比利时", "德国");
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(termsQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-terms-query.html

3. 范围查询(Range Query)

范围查询使我们能够找到在某一字段值在某个范围里的文档,字段可以是数值型,也可以是基于字符串的。范围查询只能针对单个字段。

方法: (1) gte() :范围查询将匹配字段值大于或等于此参数值的文档。

(2) gt() :范围查询将匹配字段值大于此参数值的文档。

(3) lte() :范围查询将匹配字段值小于或等于此参数值的文档。

(4) lt() :范围查询将匹配字段值小于此参数值的文档。

(5) from() 开始值 to() 结束值 这两个函数与includeLower()和includeUpper()函数配套使用。

(6) includeLower(true) 表示 from() 查询将匹配字段值大于或等于此参数值的文档。

(7) includeLower(false) 表示 from() 查询将匹配字段值大于此参数值的文档。

(8) includeUpper(true) 表示 to() 查询将匹配字段值小于或等于此参数值的文档。

(9) includeUpper(false) 表示 to() 查询将匹配字段值小于此参数值的文档。

// Query
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
rangeQueryBuilder.from(19);
rangeQueryBuilder.to(21);
rangeQueryBuilder.includeLower(true);
rangeQueryBuilder.includeUpper(true);
//RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gte(19).lte(21);
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(rangeQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();

上面代码中的查询语句与下面的是等价的:

QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gte(19).lte(21);

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-range-query.html

4. 存在查询(Exists Query)

如果指定字段上至少存在一个no-null的值就会返回该文档。

// Query
ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery("name");
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(existsQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

举例说明,下面的几个文档都会得到上面代码的匹配:

{ "name": "yoona" }
{ "name": "" }
{ "name": "-" }
{ "name": ["yoona"] }
{ "name": ["yoona", null ] }

第一个是字符串,是一个非null的值。

第二个是空字符串,也是非null。

第三个使用标准分析器的情况下尽管不会返回词条,但是原始字段值是非null的(Even though the standard analyzer would emit zero tokens, the original field is non-null)。

第五个中至少有一个是非null值。

下面几个文档不会得到上面代码的匹配:

{ "name": null }
{ "name": [] }
{ "name": [null] }
{ "user":  "bar" }

第一个是null值。

第二个没有值。

第三个只有null值,至少需要一个非null值。

第四个与指定字段不匹配。

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-exists-query.html

5. 前缀查询(Prefix Query)

前缀查询让我们匹配这样的文档:它们的特定字段已给定的前缀开始。下面代码中我们查询所有country字段以"葡萄"开始的文档。

// Query
PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("country", "葡萄");

// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(prefixQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

备注:

进行下面前缀查询,没有查找到相应信息,但是数据源中是有的:
QueryBuilder queryBuilder = QueryBuilders.prefixQuery("club", "皇家马德里");

产生以上差别的主要原因是club字段(默认mapping配置)进行了分析器分析了,索引中的数据已经不在是"皇家马德里",而country字段没有进行分析(mapping配置not_analyzed)。

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-prefix-query.html

6. 通配符查询(Wildcard Query)

通配符查询允许我们获取指定字段满足通配符表达式的文档,和前缀查询一样,通配符查询指定字段是未分析的(not analyzed)。

可以使用星号代替0个或多个字符,使用问号代替一个字符。星号表示匹配的数量不受限制,而后者的匹配字符数则受到限制。这个技巧主要用于英文搜索中,如输入““computer*”,就可以找到“computer、computers、computerised、computerized”等单词,而输入“comp?ter”,则只能找到“computer、compater、competer”等单词。注意的是通配符查询不太注重性能,在可能时尽量避免,特别是要避免前缀通配符(以以通配符开始的词条)。

// Query
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("country", "西*牙");
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(wildcardQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-wildcard-query.html

7. 正则表达式查询(Regexp Query)

正则表达式查询允许我们获取指定字段满足正则表达式的文档,和前缀查询一样,正则表达式查询指定字段是未分析的(not analyzed)。正则表达式查询的性能取决于所选的正则表达式。如果我们的正则表达式匹配许多词条,查询将很慢。一般规则是,正则表达式匹配的词条数越高,查询越慢。

// Query
RegexpQueryBuilder regexpQueryBuilder = QueryBuilders.regexpQuery("country", "(西班|葡萄)牙");

// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(regexpQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-regexp-query.html

8. 模糊查询(Fuzzy Query)

如果指定的字段是string类型,模糊查询是基于编辑距离算法来匹配文档。编辑距离的计算基于我们提供的查询词条和被搜索文档。如果指定的字段是数值类型或者日期类型,模糊查询基于在字段值上进行加减操作来匹配文档(The fuzzy query uses similarity based on Levenshtein edit distance for string fields, and a +/-margin on numeric and date fields)。此查询很占用CPU资源,但当需要模糊匹配时它很有用,例如,当用户拼写错误时。另外我们可以在搜索词的尾部加上字符 “~” 来进行模糊查询。

8.1 string类型字段

模糊查询生成所有可能跟指定词条的匹配结果(在fuzziness指定的最大编辑距离范围之内)。然后检查生成的所有结果是否是在索引中。

下面代码中模糊查询country字段为”西班牙“的所有文档,同时指定最大编辑距离为1(fuzziness),最少公共前缀为0(prefixLength),即不需要公共前缀。

// Query
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("country", "洗班牙");
// 最大编辑距离
fuzzyQueryBuilder.fuzziness(Fuzziness.ONE);
// 公共前缀
fuzzyQueryBuilder.prefixLength(0);
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(fuzzyQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();
8.2 数字和日期类型字段

与范围查询(Range Query)的around比较类似。形成在指定值上上下波动fuzziness大小的一个范围:

-fuzziness <= field value <= +fuzziness

下面代码在18岁上下波动2岁,形成[17-19]的一个范围查询:

// Query
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("age", "18");
fuzzyQueryBuilder.fuzziness(Fuzziness.TWO);
// Search
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
searchRequestBuilder.setTypes(type);
searchRequestBuilder.setQuery(fuzzyQueryBuilder);
// 执行
SearchResponse searchResponse = searchRequestBuilder.get();

参考:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-fuzzy-query.html

备注:

本代码基于ElasticSearch 2.4.1


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
1天前
|
安全 Java API
RESTful API设计与实现:Java后台开发指南
【4月更文挑战第15天】本文介绍了如何使用Java开发RESTful API,重点是Spring Boot框架和Spring MVC。遵循无状态、统一接口、资源标识和JSON数据格式的设计原则,通过创建控制器处理HTTP请求,如示例中的用户管理操作。此外,文章还提及数据绑定、验证、异常处理和跨域支持。最后,提出了版本控制、安全性、文档测试以及限流和缓存的最佳实践,以确保API的稳定、安全和高效。
|
4天前
|
存储 Java 关系型数据库
掌握Java 8 Stream API的艺术:详解流式编程(一)
掌握Java 8 Stream API的艺术:详解流式编程
19 1
|
6天前
|
Java Maven 索引
java 链接Elasticsearch
java 链接Elasticsearch
|
13天前
|
前端开发 Java API
构建RESTful API:Java中的RESTful服务开发
【4月更文挑战第3天】本文介绍了在Java环境中构建RESTful API的重要性及方法。遵循REST原则,利用HTTP方法处理资源,实现CRUD操作。在Java中,常用框架如Spring MVC简化了RESTful服务开发,包括定义资源、设计表示层、实现CRUD、考虑安全性、文档和测试。通过Spring MVC示例展示了创建RESTful服务的步骤,强调了其在现代Web服务开发中的关键角色,有助于提升互操作性和用户体验。
构建RESTful API:Java中的RESTful服务开发
|
19天前
|
Java
elasticsearch使用java程序添加删除修改
elasticsearch使用java程序添加删除修改
9 0
|
22天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
88 3
|
24天前
|
分布式计算 Java 程序员
Java 8新特性之Lambda表达式与Stream API
本文将详细介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种简洁、匿名的函数表示方法,它允许我们将函数作为参数传递给其他方法。而Stream API则是一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而提高代码的可读性和可维护性。通过本文的学习,你将能够掌握Lambda表达式和Stream API的基本用法,以及如何在项目中应用这两个新特性。
28 10
|
24天前
|
Java API 数据处理
Java 8新特性之Lambda表达式与Stream API
本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的语法结构,允许我们将函数作为参数传递给方法。而Stream API则是一种处理数据的新方式,它允许我们对数据进行更简洁、更高效的操作。通过学习这两个特性,我们可以编写出更简洁、更易读的Java代码。
|
25天前
|
Java API Maven
email api java编辑方法?一文教你学会配置步骤
在Java开发中,Email API是简化邮件功能的关键工具。本文指导如何配置和使用Email API Java:首先,在项目中添加javax.mail-api和javax.mail依赖;接着,配置SMTP服务器和端口;然后,创建邮件,设定收件人、发件人、主题和正文;最后,使用Transport.send()发送邮件。借助Email API Java,可为应用添加高效邮件功能。
|
7天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用