ElasticSearch - SpringBoot整合ES:精确值查询 term
文章目录
- 00. 数据准备
- 01. ElasticSearch 结构化搜索是什么?
- 02. ElasticSearch 结构化搜索方式有哪些?
- 03. ElasticSearch 全文搜索方式有哪些?
- 04. ElasticSearch term 查询数字?
- 05. ElasticSearch term 查询会不会计算评分?
- 06. ElasticSearch term 查询为什么会返回一个评分?
- 07. ElasticSearch 字符串类型 text?
- 08. ElasticSearch 字符串类型 keyword?
- 09. ElasticSearch term 查询字符串?
- 10. SpringBoot整合ES实现term查询?
- 11. TermQueryBuilder 源码
00. 数据准备
PUT /my_index
{
"mappings": {
"properties": {
"title": {
"type": "keyword"
},
"content": {
"type": "text"
},
"price":{
"type": "long"
}
}
}
}
PUT /my_index/_doc/1
{
"title": "金都时尚情侣浪漫主题酒店",
"content": "山东省青岛市",
"price": 337
}
PUT /my_index/_doc/2
{
"title": "金都嘉怡假日酒店",
"content": "北京市",
"price": 337
}
PUT /my_index/_doc/3
{
"title": "金都欣欣24小时酒店",
"content": "安徽省淮北市",
"price": 200
}
PUT /my_index/_doc/4
{
"title": "金都自如酒店",
"content": "上海直辖市",
"price": 300
}
PUT /my_index/_doc/5
{
"title": "自如酒店",
"content": "江苏省南京市",
"price": 400
}
01. ElasticSearch 结构化搜索是什么?
ElasticSearch 的结构化搜索是一种基于数据结构的搜索方式,它可以根据数据的字段进行过滤、排序、聚合等操作,从而精确地查询数据。比如日期、时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作。比较常见的操作包括比较数字或时间的范围,或判定两个值的大小。文本也可以是结构化的。如彩色笔可以有离散的颜色集合: 红 、 绿、蓝 。电商网站上的商品都有 UPCs 或其他的唯一标识,它们都需要遵从严格规定的、结构化的格式。
在结构化查询中,我们得到的结果总是非是即否,要么存于集合之中,要么存在集合之外。**结构化查询不关心文件的相关度或评分,它简单的对文档包括或排除处理。**这在逻辑上是能说通的,因为一个数字不能比其他数字更适合存于某个相同范围。结果只能是:存于范围之中,抑或反之。同样,对于结构化文本来说,一个值要么相等,要么不等。没有更似这种概念。
02. ElasticSearch 结构化搜索方式有哪些?
ElasticSearch 提供了多种结构化搜索方式,包括:
① 精确值查询:可以通过指定字段名和字段值来精确匹配数据,例如查询所有 age 字段等于 30 的文档。
② 范围查询:可以通过指定字段名和范围条件来查询数据,例如查询所有 age 字段大于等于 30 小于等于 40 的文档。
③ 模糊查询:可以通过指定字段名和模糊匹配条件来查询数据,例如查询所有 name 字段包含 “john” 的文档。
④ 布尔查询:可以通过组合多个查询条件来查询数据,例如查询所有 age 字段大于等于 30 并且 name 字段包含 “john” 的文档。
⑤ 聚合查询:可以对查询结果进行聚合操作,例如对所有 age 字段进行平均值计算。
⑥ 排序查询:可以通过指定字段名和排序方式来对查询结果进行排序,例如按照 age 字段升序排序。
⑦ 分页查询:可以通过指定查询结果的起始位置和数量来进行分页查询,例如查询第 10 到第 20 条数据。
以上是 ElasticSearch 常用的结构化搜索方式,可以根据具体的查询需求选择合适的方式来进行查询。
03. ElasticSearch 全文搜索方式有哪些?
ElasticSearch 提供了多种全文搜索方式,包括:
① 匹配查询:可以通过指定字段名和查询关键词来进行全文匹配查询,例如查询所有包含 “apple” 关键词的文档。
② 多字段查询:可以同时在多个字段中进行全文匹配查询,例如查询所有包含 “apple” 关键词的 title 和 content 字段的文档。
③ 短语匹配查询:可以通过指定字段名和短语关键词来进行短语匹配查询,例如查询所有包含 “apple pie” 短语的文档。
④ 前缀匹配查询:可以通过指定字段名和前缀关键词来进行前缀匹配查询,例如查询所有以 “app” 开头的文档。
⑤ 正则表达式查询:可以通过指定字段名和正则表达式来进行正则匹配查询,例如查询所有 content 字段中包含数字的文档。
⑥ 模糊查询:可以通过指定字段名和模糊匹配条件来进行模糊匹配查询,例如查询所有 content 字段中包含 “appl” 的文档。
⑦ 搜索建议:可以根据用户输入的关键词提供搜索建议,例如输入 “app” 后自动提示 “apple”。
以上是 ElasticSearch 常用的全文搜索方式,可以根据具体的查询需求选择合适的方式来进行查询。
04. ElasticSearch term 查询数字?
在 ElasticSearch 中,term 查询是一种用于查找指定字段中包含指定值的文档的查询方式。term 查询是一种精确匹配查询,它会精确地匹配指定字段中的值,不会对查询关键词进行分词处理。term 查询可以用它处理数字、布尔值、日期以及字符串。
当进行精确值查找时, 我们会使用过滤器(filters),过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。
GET /my_index/_search
{
"query": {
"term": {
"price": {
"value": "337"
}
}
}
}
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "金都时尚情侣浪漫主题酒店",
"content" : "山东省青岛市",
"price" : 337
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "金都嘉怡假日酒店",
"content" : "北京市",
"price" : 337
}
}
]
}
}
上述查询语句表示在 my_index 索引中查找 price字段中包含值为 “337” 的文档。如果查询成功,ElasticSearch 将返回所有符合条件的文档。
需要注意的是,term 查询是一种精确匹配查询,它不会对查询关键词进行分词处理。因此,如果查询关键词包含多个单词,term 查询可能无法匹配到任何文档。在这种情况下,可以考虑使用 match 查询或者 phrase 查询等其他查询方式。
GET /my_index/_search
{
"query": {
"term": {
"title": {
"value": "金都时尚"
}
}
}
}
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
05. ElasticSearch term 查询会不会计算评分?
ElasticSearch 的 term 查询不会计算评分,它是一种精确匹配查询,只会返回精确匹配的文档,不会对文档进行评分排序。
在 ElasticSearch 中,查询语句可以分为两种类型:查询(query)和过滤器(filter)。查询语句会对文档进行评分排序,而过滤器则不会对文档进行评分排序。term 查询属于过滤器类型的查询语句,它只会返回精确匹配的文档,不会对文档进行评分排序。
因此,如果需要对文档进行评分排序,可以使用查询语句(如 match 查询、bool 查询等),如果只需要返回精确匹配的文档,可以使用过滤器语句(如 term 查询、range 查询等)。
06. ElasticSearch term 查询为什么会返回一个评分?
在 ElasticSearch 中,虽然 term 查询是一种过滤器类型的查询语句,不会对文档进行评分排序,但是在某些情况下,term 查询仍然会返回一个评分。这是因为在 ElasticSearch 中,每个文档都有一个 _score 属性,表示该文档与查询条件的相关性得分。即使是过滤器类型的查询语句,ElasticSearch 仍然会计算每个文档与查询条件的相关性得分,并将其存储在 _score 属性中。
在 term 查询中,如果查询条件只匹配了一个文档,那么该文档的 _score 属性值将为 1.0,表示该文档与查询条件的相关性得分为最高。如果查询条件匹配了多个文档,那么所有匹配的文档的 _score 属性值都将为 1.0,表示它们与查询条件的相关性得分相同。
虽然 term 查询会返回一个评分,但是该评分并不会影响查询结果的排序。在 term 查询中,所有匹配的文档的 _score 属性值都相同,因此它们的排序顺序将根据其他因素(如文档的创建时间、更新时间等)来确定。
GET /my_index/_search
{
"query": {
"term": {
"price": {
"value": "337"
}
}
}
}
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "金都时尚情侣浪漫主题酒店",
"content" : "青岛",
"price" : 337
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "金都嘉怡假日酒店",
"content" : "北京",
"price" : 337
}
}
]
}
}
07. ElasticSearch 字符串类型 text?
在 ElasticSearch 中,字符串类型 text 是一种用于存储文本的数据类型。text 类型会对文本进行分词处理,将文本分成一个个词条,然后将这些词条存储到倒排索引中,以便进行全文搜索。
由于text 类型会对文本进行分词处理,因此在进行查询时,需要使用全文搜索查询方式(如 match 查询、multi_match 查询等),而不能使用精确匹配查询方式(如 term 查询、terms 查询等)。
例如:根据我们构造的数据,content 字段为 text 类型,且数据库中存在数据:
PUT /my_index/_doc/1
{
"title": "金都时尚情侣浪漫主题酒店",
"content": "山东省青岛市",
"price": 337
}
① 使用精确匹配 term 查询,查询结果为空:
GET /my_index/_search
{
"query": {
"term": {
"content": {
"value": "山东省青岛市"
}
}
}
}
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
② 使用全文检索 match查询,查询结果为:
GET /my_index/_search
{
"query": {
"match": {
"content": "山东省青岛市"
}
}
}
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : 5.805786,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 5.805786,
"_source" : {
"title" : "金都时尚情侣浪漫主题酒店",
"content" : "山东省青岛市",
"price" : 337
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.5889417,
"_source" : {
"title" : "金都欣欣24小时酒店",
"content" : "安徽省淮北市",
"price" : 200
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "5",
"_score" : 0.5889417,
"_source" : {
"title" : "自如酒店",
"content" : "江苏省南京市",
"price" : 400
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.10522305,
"_source" : {
"title" : "金都嘉怡假日酒店",
"content" : "北京市",
"price" : 337
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "4",
"_score" : 0.08840232,
"_source" : {
"title" : "金都自如酒店",
"content" : "上海直辖市",
"price" : 300
}
}
]
}
}
因此,由于 text 类型会对文本进行分词处理,因此在进行查询时,需要使用全文搜索查询方式(如 match 查询、multi_match 查询等),而不能使用精确匹配查询方式(如 term 查询、terms 查询等)。
08. ElasticSearch 字符串类型 keyword?
在 ElasticSearch 中,字符串类型 keyword 是一种用于存储精确值的数据类型。keyword 类型不会对文本进行分词处理,而是将整个文本作为一个词条进行索引,以便进行精确匹配查询。
由于 keyword 类型不会对文本进行分词处理,因此在进行查询时,需要使用精确匹配查询方式(如 term 查询、terms 查询等),而不能使用全文搜索查询方式(如 match 查询、multi_match 查询等)。
例如:根据我们构造的数据,title 字段为 keyword 类型,且数据库中存在数据:
PUT /my_index/_doc/1
{
"title": "金都时尚情侣浪漫主题酒店",
"content": "山东省青岛市",
"price": 337
}
使用精确匹配 term 查询,查询结果为:
GET /my_index/_search
{
"query": {
"term": {
"title": {
"value": "金都时尚情侣浪漫主题酒店"
}
}
}
}
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862944,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862944,
"_source" : {
"title" : "金都时尚情侣浪漫主题酒店",
"content" : "山东省青岛市",
"price" : 337
}
}
]
}
}
09. ElasticSearch term 查询字符串?
在 ElasticSearch 中,term 查询是一种用于精确匹配查询的查询方式,可以用于查询 keyword 类型的文本。term 查询会将查询关键词作为一个整体进行匹配,只有当查询关键词与文档中的词条完全匹配时,才会返回匹配的文档。
以下是一个使用 term 查询进行查询的示例:
GET /my_index/_search
{
"query": {
"term": {
"title": {
"value": "金都时尚情侣浪漫主题酒店"
}
}
}
}
使用 term 查询对名为 “my_index” 的索引中的 “title” 字段进行查询,查询关键词为 “John Doe”。由于 “title” 字段的类型为 keyword,因此 term 查询会将查询关键词作为一个整体进行匹配,只有当文档中的 “title” 字段的值与查询关键词完全匹配时,才会返回匹配的文档。
由于 term 查询是一种精确匹配查询方式,因此在进行查询时,需要确保查询关键词与文档中的词条完全匹配,否则可能会导致查询结果不准确。
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862944,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862944,
"_source" : {
"title" : "金都时尚情侣浪漫主题酒店",
"content" : "山东省青岛市",
"price" : 337
}
}
]
}
}
10. SpringBoot整合ES实现term查询?
GET /my_index/_search
{
"query": {
"term": {
"price": {
"value": "337"
}
}
}
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("price",337);
searchSourceBuilder.query(termQueryBuilder);
SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(searchResponse);
}
}
11. TermQueryBuilder 源码
public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
public static final String NAME = "term";
private static final ParseField TERM_FIELD = new ParseField("term");
private static final ParseField VALUE_FIELD = new ParseField("value");
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, String) */
public TermQueryBuilder(String fieldName, String value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, int) */
public TermQueryBuilder(String fieldName, int value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, long) */
public TermQueryBuilder(String fieldName, long value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, float) */
public TermQueryBuilder(String fieldName, float value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, double) */
public TermQueryBuilder(String fieldName, double value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, boolean) */
public TermQueryBuilder(String fieldName, boolean value) {
super(fieldName, (Object) value);
}
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, Object) */
public TermQueryBuilder(String fieldName, Object value) {
super(fieldName, value);
}
}