elasticsearch中DSL之Full text queries(全文搜索)

全文搜索

全文搜索是应用到字段类型为text上的搜索,也是es重要特性,es会根据字段的分词器算法,把字段进行解析,根据解析后的结果在es服务器中利用倒排索引算法,获取多个文档,并给出相应的得分。

搜索和过滤的区别

  • 搜索要给出每个文档得分
  • 过滤不计算每个文档得分,而且过滤会把数据缓存起来。

全匹配

全部匹配,每个文档得分都是1

GET myindex/_search
{
    "query": {
        "match_all": {   
        }
    }
}

全部不匹配

GET myindex/_search
{
    "query": {
        "match_none": {   
        }
    }
}

1.Match Query

match是只要文档包含任何一个分词,都要返回(分词间没有顺序依赖)
match是一个布尔查询,可能这句话不太了解这句话的含义。这是因为通常我们看到的查询语句的写法是下例:

GET myindex/_search
{
    "query": {
        "match": {
           "addr":"hangzhou shenzhen"
        }
    }
}

其实上面的简写的语法,真正的语法格式是下面:

GET myindex/_search
{
    "query": {
        "match": {
           "addr": {
               "query" :"hangzhou shenzhen",
               "operator" : "or"
           }
        }
    }
}

所以match有很多属性,就是在这里定义的,上例表示addr只要有hangzhou,shenzhen任何一个词元都要返回文档。
响应的结果:

"hits": {
      "total": 2,
      "max_score": 0.25316024,
      "hits": [
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "2",
            "_score": 0.25316024,
            "_source": {
               "name": "mahuateng",
               "age": "40",
               "addr": "zhongguo guangdong shenzhen",
               "city": "shenzhen"
            }
         },
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "1",
            "_score": 0.25316024,
            "_source": {
               "name": "mayun",
               "age": "43",
               "addr": "zhongguo zhejiang hangzhou",
               "city": "hangzhou"
            }
         }
      ]
   }

如果把"operator" : "or"改为"operator" : "and"则不会返回文档。
同样还有很多其他的属性:

  • query:实际被解析的语句
  • operator:操作符,“and” 或者 “or”,默认是"or"
  • lenient:布尔值,默认false,表示格式配置失败是否失败(例如用字符串查整型字段)
  • minimum_should_match:或逻辑,最小要匹配几个逻辑
  • analyzer:分词器
  • zero_terms_query : 文档只有停顿词,是否返回,默认是none, 还有all
  • max_expansions:是指可以扩展最大词项。
  • fuzziness:设置模糊性,默认是AUTO
    还有很多其他的属性,就不介绍了

下面重点说下fuzziness模糊性的用法,因为对于英文语法有词根,词缀的语法,所以一个单词可以有多种变形,所以模糊性搜索就变得很常用了。(对于中文这种用法就没用了)
根据官网解释:
fuzziness is interpreted as a Levenshtein Edit Distance — the number of one character changes that need to be made to one string to make it the same as another string.就是从一个单词变成另一个单词需要编辑的次数。

fuzziness有两种表示方式:

  • 0 或 1 或 2,表示编辑距离(可以大于2,但是和2作用一样)
  • AUTO :是一个算法。
    目标单词长度为 0 到 2 之间时,必须要精确匹配
    目标单词长度为 3 到 5 之间时,最大编辑距离为 1
    目标单词长度大于5,最大编辑距离为 2
    举个栗子:用said去查say是查不到的,因为最大编辑距离是2才能找到。
  • 另外还可以设置前缀不能模糊的长度prefix_length

match最基础的全文索引语法,所以其他的语法,都是在此基础上扩展的。(通过使用不同的参数可以构建其他的检索语法)

2.Match Phrase Query

match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的。

GET myindex/_search
{
    "query": {
        "match_phrase": {
           "addr": "zhongguo guangdong"
        }
    }
}

例如上例:返回文档中,addr中必须包含zhongguoguangdong而且他们的顺序是不变的,也要保证他们之间没有其他的有效词。
返回结果:

"hits": [
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "2",
            "_score": 0.82712996,
            "_source": {
               "name": "mahuateng",
               "age": "40",
               "addr": "zhongguo guangdong shenzhen",
               "city": "shenzhen"
            }
         },
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "1",
            "_score": 0.5063205,
            "_source": {
               "name": "renzhenfei",
               "age": "71",
               "addr": "zhongguo guangdong guangzhou",
               "city": "guangzhou"
            }
         }
      ]

短语查询有个重要参数:slop,可以容忍查询词之间位置跳过位置,默认值为0(注意:之间的跳跃位置的范围是[0, slop],并不是必须跳过slop个位置)
注意:如果要使用参数,就不能使用简易语法了。
例如:

GET myindex/_search
{
    "query": {
        "match_phrase": {
           "addr": {
               "query" :"zhongguo shenzhen",
               "slop" : 3
           }
        }
    }
}

返回的文档:可以发现,zhongguo shenzhen之间只有一个guangdong

"hits": [
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "2",
            "_score": 0.5266491,
            "_source": {
               "name": "mahuateng",
               "age": "40",
               "addr": "zhongguo guangdong shenzhen",
               "city": "shenzhen"
            }
         }
      ]

3.Match Phrase Prefix Query

是对match_phrase的扩充,只是会对查询文本的分词后最后一个分词,可以前缀模糊查询。
有个重要的参数max_expansions可以指定模糊度[0, max_expansions]。
例如:

GET myindex/_search
{
    "query": {
        "match_phrase_prefix": {
           "addr": {
               "query" :"zhongguo guangdong shen",
               "max_expansions" : 10
           }
        }
    }
}

返回的结果是:

"hits": [
         {
            "_index": "myindex",
            "_type": "mytype",
            "_id": "2",
            "_score": 1.4820052,
            "_source": {
               "name": "mahuateng",
               "age": "40",
               "addr": "zhongguo guangdong shenzhen",
               "city": "shenzhen"
            }
         }
      ]

但是我发现下面的语法也能返回上述结果:(如果哪位大神指导为什么,也可以评论告知)

GET myindex/_search
{
    "query": {
        "match_phrase_prefix": {
           "addr": {
               "query" :"zhongguo guangdong shen",
               "max_expansions" : 1
           }
        }
    }
}

4.Multi Match Query

multi_match查询建立在match查询之上,重要的是它允许对多个字段查询。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

multi_match内部如何执行是由参数type决定的。下面是type的可选值

  • best_fields:默认方式,会将任何与查询匹配的文档作为结果返回,但是只使用最佳字段的 _score 评分作为评分结果返回。(使用场景是查询文档含有多个有效词,一个文档同时含有多个有效词要比只含有一个有效词的文档得分高)。
  • most_fields:会将任何与查询匹配的文档作为结果返回,但是所有字段的评分合并起来作为评分结果返回。
  • cross_fields:将查询字符串分词后每个分词,在查询的字段中都去查询每个分词(当要求多个字段都应该查询到的时候适合该方式)
  • phrase:和best_fields相似,只是内部使用的是match_phrase
  • phrase_prefix:和best_fields相似,只是内部使用的是match_phrase_prefix
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值