本文以6.8版本为例
1. Query DSL
1.1 Query and Filter context
其实其本质就是两个内容,一个是Query context,顾名思义就是查询上下文,其返回的内容会包含该文档与查询的上下文有多匹配,如这句话的描述“how well does this document match this query clause?”,当然其中也会返回一个匹配得分“_score”; 另外一个是Filter context,中文叫做过滤上下文,其实本质就是过滤用的,其返回的内容会包含该文档是否符合这个查询,如下面这句话的描述“Does this document match this query clause?”, 具体可以查看上边的英文描述,看不懂就翻译一下吧。
例子:
# 其中的query包含的是查询上下文,而filter包含的是过滤上下文。
GET /_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
1.2 Match All Query
其实这个模块包含了两个内容:
-
Match All Query
据官网的描述,它说的是这个是最简单的查询了,这个查询会匹配所有的文档,且将所有返回的文档的匹配得分设置为1.0,当然也可以通过设置boost
,修改这个返回的得分。 -
Match None Query
与Match All Query 相反,这个将不会匹配任何的文档。 -
例子:
# match all query
GET /_search
{
"query": {
"match_all": {}
}
}
GET /_search
{
"query": {
"match_all": { "boost" : 1.2 }
}
}
# match none query
GET /_search
{
"query": {
"match_none": {}
}
}
1.3 Full text queries
用于搜索被分词后的text类型字段,查询字符串会用索引数据时相同的analyzer对其进行解析。
-
Match query
即默认情况下,下面的查询并不只是查询到了含有这句歌词的文档,而是分词器在对All I need is someone who makes me wanna sing
进行分词后,凡是匹配其中的任意一个内容的情况下都会匹配成功,这是因为其使用了 "or" 的匹配逻辑。
GET /songs_v1/_search
{
"query": {
"match": {
"lyrics": "All I need is someone who makes me wanna sing"
}
}
}
如果要解决这个问题,就需要将or
修改成and
,此时,将只会匹配包含有All I need is someone who makes me wanna sing
这句歌词的文档。
GET /songs_v1/_search
{
"query": {
"match": {
"lyrics": {
"query": "All I need is someone who makes me wanna sing",
"operator": "and"
}
}
}
}
此外match query还可以通过fuzziness进行模糊匹配的配置,即可以配置有多少个字母不一样的情况。下面是允许有一个字母不一样的情况
GET /songs_v1/_search
{
"query": {
"match": {
"lyrics": {
"query": "All I need is somene who makes me wanna sing",
"operator": "and",
"fuzziness": 1
}
}
}
}
-
Match Phrase Query:短语匹配查询
试想一种情况:
有一句歌词take me to your heart
,如果我们想要使用take me匹配的话,如果直接用match query + and 的话的确可以匹配出来结果,但是take me
却有可能是分隔开的,此时如果使用match_phrase,就可以确保成功了。
GET /songs_v1/_search
{
"query": {
"match_phrase": {
"lyrics": {
"query": "take me"
}
}
}
}
而如果有一种情况,就是我知道有take
这个单词且两个还是三个单词之后有一个your
,但是中间的我忘了,那么要如何进行查询呢?其实也很简单。集合使用slop即可,但是注意哦,如果这里将slop设置为1,是无法匹配成功的哦。
GET /songs_v1/popular/_search
{
"query": {
"match_phrase": {
"songName": {
"query": "take your ",
"slop": 3
}
}
}
}
-
Match Phrase Prefix Query
顾名思义啦,就是短语前缀匹配,前缀懂吧?嗯嗯,就那个前缀。例子如下所示,其实就是如果分词后的某个短语是以提供的短语开头的就能匹配上(我觉得是这个意思,如果不对,欢迎指正)。
#match phrase prefix query
GET /songs_v1/_search
{
"query": {
"match_phrase_prefix": {
"songName": "take me"
}
}
}
-
Multi Match Query
即可以同时对多个字段进行查询,没啥解释的,直接上例子,(注:也可以使用通配符如*等,具体查看官网):
#multi match query
GET /songs_v1/_search
{
"query": {
"multi_match": {
"query": "take me to your heart",
"fields": ["songName", "lyrics"]
}
}
}
-
Common Terms Query:常用术语查询
-
问1、什么是停用词?索引时做停用词处理的目的是什么?
答:如常见的英文中的 his 、her、my、mine,中文的 他、她、它、地等等。因为这些词出现的频率太多了 -
问2、如果在索引时应用停用词处理,下面的两个查询会查询什么词项?
the brown fox
: 会得出brown fox
的结果
not happy
: 会得出happy
结论:索引时应用停用词处理会影响查询精度?若不做停用词处理,会应向查询,如何协调这两个问题呢?
Common terms query会区分高频词、低频词,我们可以通过cutoff_frequency来指定一个分界值,将搜索文本中的词分为高频词和低频词,低频词的重要性高于高频词。
先对低频词进行搜索,并计算所有匹配文档相关性得分;
再搜索和高频词匹配的文档,这会搜到很多文档,不计算得分
取交集,交集中的文档进行高频词得分计算
高频词的得分和低频词得分相加,作为文档得分。实际执行的搜索是必须包含低频词+或包含高频词。
思考:这样处理下,如果用户输入的都是高频词如“to be or not to be”结果会是怎样的?你希望是怎样的?
解决办法:如果都是高频词,让用户可以自己定对高频词做and/or操作,目己定对低频词进行and/or操作;或指定最少得多少个同时匹配。
#Common terms query
GET /songs_v1/_search
{
"query": {
"common": {
"message": {
"query": "take me to your heart",
# 出现的百分比,如果高于则为高频词,反之则是低频词,也可以是整数,此时表示出现次数
"cutoff_frequency": 0.001,
# 对低频词做or操作,也可以设置为and操作
"low_freq_operator" : "or",
# 对高频词做or操作,也可以设置为and操作
"high_freq_operator" : "or",
# 表示最低需要匹配多少个才是相关的
"minimum_should_match": {
"high_freq": 2,
"low_freq": 2
}
}
}
}
-
Query String Query
可以使用lucene的语法进行搜索
#Query String query
GET /bank/_search
{
"query": {
"query_string" : {
"default_field" : "content",
"query" : "address:(green OR street) AND gender:F"
}
}
}
-
Simple Query String Query
下图表示不同的字符组合表示什么意思,还是挺重要的哦:
- 例子:
#Simple uery String query
GET /bank/_search
{
"query": {
"simple_query_string" : {
"fields" : ["address"],
"query" : "street*"
}
}
}
1.4 Term-level queries
-
Term Query
其实只要记住一点,它不会对查询串进行分词,所以一般查询的时候要搭配XXXX.keyword进行,其他的特点请查看官网比较好。
#term query
GET /bank/_search
{
"query": {
"term": {
"_id": {
"value": "50"
}
}
}
}
GET /bank/_search
{
"query": {
"term": {
"firstname.keyword": {
"value": "Aurelia"
}
}
}
}
-
Terms Query
与term查询基本一致,不过可以对多个词进行查询
# terms query
# 例子1
GET /bank/_search
{
"query": {
"terms": {
"age": [
40,
33
]
}
}
}
# 例子2
GET /bank/_search
{
"query" : {
"terms" : {
"address.keywor创":[
"806 Rockwell Place",
"502 Baycliff Terrace"
]
}
}
}
当然还有其他的用法,如terms lookup
例子:
#这个例子表示要查询在tweets中user在 索引为users下的id为2的doc中followers的人。
GET /tweets/_search
{
"query" : {
"terms" : {
"user" : {
"index" : "users",
"type" : "_doc",
"id" : "2",
"path" : "followers"
}
}
}
}
#另一个例子
#Terms lookup
#类比
# select * from bank where city in ( select city_id from citys );
GET /bank/_search
{
"query": {
"terms": {
"age":{
"index" : "bank",
"type" : "account",
"id" : "6",
"path" : "age"
}
}
}
}
- Range Query
即范围查询:
- 例子:
# range query
# >= 20 <=30
GET /bank/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
}
-
Exists Query
即查询某个字段不为null或者[]的文档:
- 例子:
#exists query
GET /bank/_search
{
"query": {
"exists": {
"field": "numbers"
}
}
}
也可以结合must_not查询不包含某个字段的文档
- 例子:
#不包含某个字段的文档
GET /bank/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "age"
}
}
]
}
}
}
-
Prefix Query
前缀查询,表示查询某个字段且前缀匹配的文档。
- 例子:
# prefix query
# 表示email字段中前缀为foster的文档
GET /bank/_search
{
"query": {
"prefix": {
"email.keyword": {
"value": "foster"
}
}
}
}
-
Wildcard Query:通配符查询
- 例子:
# wildcard query 通配符查询
# ? 代表单个字符
# * 0或多个字符
GET /bank/_search
{
"query": {
"wildcard": {
"email.keyword": {
"value": "*ware*"
}
}
}
}
-
Regexp Query
image.png
- 例子:
#regexp query
GET /_search
{
"query": {
"regexp": {
"user": {
"value": "k.*y",
"flags" : "ALL",
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}
1.5 Compound queries
compound queries会包裹其他compound queries或leaf queries,合并它们的查询结果及相关性得分,改变他们的行为。
-
Constant Score Query
这个查询不会提供匹配得分,但是会根据提供的boost返回相应的值。
- 例子:
# constant_score
GET /bank/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"age": 24
}
},
"boost": 1.2
}
}
}
-
Bool Query
- 例子:
# 找到岁数不小于40岁的人
GET /bank/_search
{
"query": {
"bool": {
"must_not": [
{
"range": {
"age": {
"lt": 40
}
}
}
]
}
}
}
如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~
网友评论