Open BlackHole1 opened 5 years ago
上一篇:Elasticsearch搜索-基本搜索(第一章)
上节基本都是以 term 进行搜索,但其实 Elasticsearch 提供了很多搜索方法,本章就是介绍 Elasticsearch 有哪些搜索方法、分别起的作用。
term
Elasticsearch
本章对 common_terms query、query_string query、simple_query_string query 没有解释说明,因为使用起来较少,而且解释起来较为麻烦。如果想了解,可以参考网上的文章。这里就不在阐述了。
common_terms query
query_string query
simple_query_string query
我们先使用 term 进行一次查询:
GET books/_search { "_source": ["title", "author"], "query": { "term": { "title": "java编程" } } }
你会发现,其结果为空(但是数据库里是有这个数据的),如图:
这是因为 term 是匹配分词后的词项来进行查询的。比如刚刚我们查的 java编程 ,在 Elasticsearch 进行分词时,会把 java编程 分为:java 和 编程 。导致匹配不起来。
java编程
java
编程
用代码诠释的话就是:
const keyword = 'java编程'; const data = ['java', '编程']; const result = data.includes(keyword); console.log(result) //=> false
现在我们把 term 换成 match 来尝试下:
match
GET books/_search { "_source": ["title", "author"], "query": { "match": { "title": "java编程" } } }
结果如图:
可以发现,已经有结果了,但是为什么会有两个呢?
原因是因为 match 会对你的关键字进行分词,然后去匹配文档分词后的结果,只要文档里的词项能匹配关键字分词后的任何一个,都会返回到结果里。
代码诠释:
const data = ['java', '编程', '思想']; // 分词后的文档里的数据 const keywords = ['java', '编程', '思想']; // 分词后的关键字 const result = (() => { for (let x = 0; x < data.length; x++) { const dataItem = data[x]; for (let y = 0; y < keywords.length; y++) { const keywordItem = keywords[y]; if (dataItem === keywordItem) { return true; } } } return false; })()
如果我只想让它返回一个呢,并且只能用 match 来做,可以么?
是可以的,match 提供了一个属性:operator。可以用这个来帮助完成这个需求:
operator
GET books/_search { "_source": ["title", "author"], "query": { "match": { "title": { "query": "java编程", "operator": "and" } } } }
最终的结果如图:
原理是因为 operator 属性的值为 and,这样的话,就告诉 Elasticsearch 我要让我的关键字都能和文档里的词项匹配上。有一个没匹配上,我都不要。
and
如果 operator 属性的值为 or,那结果就和之前是一样的了。
or
你可以把这个方法理解为自带了 operator 属性的值为 and 的 match。
这个方法有两个限制条件,只有都满足,才会在结果中显示出:
operator: "and"
顺序一致指的是什么呢?
假设你使用 match 来匹配: 编程java,那么结果还是和上面一样。所以如果你需要要求顺序一致性,那么你就可以使用 match_phrase 来做。
编程java
match_phrase
如果使用 编程java 来搜索:
如果使用 java编程:
这个方法和 match_phrase 方法类似,不过这个方法可以可以把最后一个词项作为前缀进行匹配,想象一下:用户在搜索栏中搜索 辣鸡UZ,然后下面列表中出现了 辣鸡UZI。
辣鸡UZ
辣鸡UZI
首先 match_phrase_prefix 会先分词为: 辣鸡,然后找了一个文档,再然后匹配 辣鸡 后面的字符串是否以 UZ 开头的。这个时候文档满足条件,就返回出结果。可以假想后面一直有一个(.*)的通配符,如:辣鸡UZ(.*)。
match_phrase_prefix
辣鸡
UZ
(.*)
辣鸡UZ(.*)
知道原理了,我们现在写一个查询语句:
GET books/_search { "_source": ["title", "author"], "query": { "match_phrase_prefix": { "title": "java编" } } }
multi_match 是 match 的升级方法,可以用来搜索多个字段。
multi_match
比如我不想只在 title 里搜索 java编程,我还想在 description 里进行搜索。那应该怎么做呢?
title
description
Elasticsearch 已经提供了 multi_match 专门用来处理这件事情:
GET books/_search { "_source": ["title", "description"], "query": { "multi_match": { "query": "java编程", "fields": ["title", "description"] } } }
最终结果如图:
并且 multi_match 还支持通配符。上面的查询语句,可以写成:
GET books/_search { "_source": ["title", "description"], "query": { "multi_match": { "query": "java编程", "fields": ["title", "*tion"] } } }
下一篇:Elasticsearch搜索-词项查询(第三章)
Elasticsearch搜索-全文查询(第二章)
上一篇:Elasticsearch搜索-基本搜索(第一章)
全文查询
上节基本都是以
term
进行搜索,但其实Elasticsearch
提供了很多搜索方法,本章就是介绍Elasticsearch
有哪些搜索方法、分别起的作用。本章对
common_terms query
、query_string query
、simple_query_string query
没有解释说明,因为使用起来较少,而且解释起来较为麻烦。如果想了解,可以参考网上的文章。这里就不在阐述了。match query
我们先使用
term
进行一次查询:你会发现,其结果为空(但是数据库里是有这个数据的),如图:
这是因为
term
是匹配分词后的词项来进行查询的。比如刚刚我们查的java编程
,在Elasticsearch
进行分词时,会把java编程
分为:java
和编程
。导致匹配不起来。用代码诠释的话就是:
现在我们把
term
换成match
来尝试下:结果如图:
可以发现,已经有结果了,但是为什么会有两个呢?
原因是因为
match
会对你的关键字进行分词,然后去匹配文档分词后的结果,只要文档里的词项能匹配关键字分词后的任何一个,都会返回到结果里。代码诠释:
如果我只想让它返回一个呢,并且只能用
match
来做,可以么?是可以的,
match
提供了一个属性:operator
。可以用这个来帮助完成这个需求:最终的结果如图:
原理是因为
operator
属性的值为and
,这样的话,就告诉Elasticsearch
我要让我的关键字都能和文档里的词项匹配上。有一个没匹配上,我都不要。如果
operator
属性的值为or
,那结果就和之前是一样的了。match_phrase query
你可以把这个方法理解为自带了
operator
属性的值为and
的match
。这个方法有两个限制条件,只有都满足,才会在结果中显示出:
operator: "and"
顺序一致指的是什么呢?
假设你使用
match
来匹配:编程java
,那么结果还是和上面一样。所以如果你需要要求顺序一致性,那么你就可以使用match_phrase
来做。如果使用
编程java
来搜索:如果使用
java编程
:match_phrase_prefix query
这个方法和
match_phrase
方法类似,不过这个方法可以可以把最后一个词项作为前缀进行匹配,想象一下:用户在搜索栏中搜索辣鸡UZ
,然后下面列表中出现了辣鸡UZI
。首先
match_phrase_prefix
会先分词为:辣鸡
,然后找了一个文档,再然后匹配辣鸡
后面的字符串是否以UZ
开头的。这个时候文档满足条件,就返回出结果。可以假想后面一直有一个(.*)
的通配符,如:辣鸡UZ(.*)
。知道原理了,我们现在写一个查询语句:
结果如图:
multi_match query
multi_match
是match
的升级方法,可以用来搜索多个字段。比如我不想只在
title
里搜索java编程
,我还想在description
里进行搜索。那应该怎么做呢?Elasticsearch
已经提供了multi_match
专门用来处理这件事情:最终结果如图:
并且
multi_match
还支持通配符。上面的查询语句,可以写成:下一篇:Elasticsearch搜索-词项查询(第三章)