《Elasticsearch:权威指南》Query DSL -- Full text queries -- Match Query

Match Query

匹配查询可以接受文本、数字及日期数据,进行分析然后构造查询。

GET /_search
{
    "query": {
        "match" : {
            "message" : "this is a test"
        }
    }
}

注意:message是字段名称,你可以替换任何字段的名称。

match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配,因此相比于term的精确搜索,match是分词匹配搜索,match搜索还有两个相似功能的变种,一个是match_phrase,一个是multi_match

例如,当我们搜索 “中国杭州”,搜索词会先分词为“中国”和“杭州”,只要文档中包含“中国“和“杭州“任意一个词,都会被搜索到。同term查询一样,最终能否查到结果也取决于文档的内部存储结构结构,内部存储结构有分词和未分词2种情况,具体参见Term Query中 “term query 和 match query的不同之处”章节

match

match query 查询的类型为boolean, 这意味着将对提供的查询文本进行分析,并且分析过程将从提供的文本中构造一个boolean查询。运算符标志可以设置为orand控制布尔子句(默认为or)。 可以使用minimum_should_match这个参数来设置要匹配的可选的should子句的最小数量。

这是一个提供其他参数的示例(请注意结构略有变化,消息是字段名称):

GET /_search
{
    "query": {
        "match" : {
            "message" : {
                "query" : "this is a test",
                "operator" : "and"   //操作设置为and,表明分词后,每个词都要存在
            }
        }
    }
}

可以将分析器设置为控制哪个分析器将对文本执行分析过程。 它默认为字段显式映射定义或默认的搜索分析器。

可以将lenient参数设置为true,以忽略由数据类型不匹配引起的异常,例如尝试使用文本查询字符串查询数字字段。 默认为false

operator参数例子

我们来看个operator的实际例子,仍然复用Term Query中 “term query 和 match query的不同之处”章节的索引结构和数据:

1.建索引和插入一条数据
PUT my_index     //建一个索引
{
  "mappings": {
    "_doc": {
      "properties": {
        "full_text": {                 
          "type":  "text"       //text类型,会分词
        },
        "exact_value": {
          "type":  "keyword"  //keyword类型,不会分词
        }
      }
    }
  }
}

PUT my_index/_doc/1   //插入一条数据
{
  "full_text":   "Quick Foxes!", 
  "exact_value": "Quick Foxes!"  
}
2.默认值or查询

我们针对full_text字段进行查询,full_text内部存储是分词的, 内部存储为[quick, foxes],2个单词,我们使用match查询时,查询条件也会分词,分词结果为[quick, run],2个单词,那么operator默认为 or,即查询条件数组中的单词,只要有一个符合存储数组中的值,那么认为匹配,如果匹配的个数越多,则score越大,排序越靠前。

curl  -XGET "10.40.164.63:9200/my_index/_search"  --header "Content-Type:application/json" -d ' 
{
  "query": {
    "match": {
      "full_text": "Quick run!"    //查询条件分词后第二个词是run,而内部存储的是Foxes
    }
  }
}'

注意:查询条件分词后第二个词是run,而内部存储的是Foxes

上面的例子结果:

{
	"took": 3,
	"timed_out": false,
	"_shards": {
		"total": 5,
		"successful": 5,
		"skipped": 0,
		"failed": 0
	},
	"hits": {
		"total": 1,     //查询到了
		"max_score": 0.2876821,    //如果查询条件为“Quick Foxes”,得分翻倍为0.5753642
		"hits": [{
			"_index": "my_index",
			"_type": "_doc",
			"_id": "1",
			"_score": 0.2876821,
			"_source": {
				"full_text": "Quick Foxes!",
				"exact_value": "Quick Foxes!"
			}
		}]
	}
}
2.and查询

即查询条件数组中的单词,全部符合存储数组中的值,那么认为匹配,只要有一个不符合,则不匹配。

curl  -XGET "10.40.164.63:9200/my_index/_search"  --header "Content-Type:application/json" -d ' 
{
  "query": {
    "match": {
      "full_text": {
                "query" : "Quick run!",
                "operator" : "and"   //and查询
            }
    }
  }
}'

由于分词后的run不符合,因此查询结果为空。

fuzziness

模糊性允许基于要查询的字段类型进行模糊匹配。 有关允许的设置,请参见“模糊性”。

在这种情况下,可以设置prefix_lengthmax_expansions来控制模糊过程。 如果设置了模糊选项,则查询将使用top_terms_blended_freqs _ $ {max_expansions}作为其重写方法,Fuzzy_rewrite参数允许控制如何重写查询。

默认情况下允许使用模糊转置(ab→ba),但可以通过将Fuzzy_transpositions设置为false来禁用模糊转置。

请注意,“模糊匹配”不适用于带有同义词的“词语”,因为在引擎盖下,这些术语被扩展为混合术语频率的特殊同义词查询,这不支持模糊扩展。

GET /_search
{
    "query": {
        "match" : {
            "message" : {
                "query" : "this is a testt",
                "fuzziness": "AUTO"
            }
        }
    }
}

模糊性

模糊匹配 对待 “模糊” 相似的两个词似乎是同一个词。首先,我们需要对我们所说的 模糊性 进行定义。

在1965年,Vladimir Levenshtein 开发出了 Levenshtein distance, 用来度量从一个单词转换到另一个单词需要多少次单字符编辑。他提出了三种类型的单字符编辑:

  • 一个字符 替换 另一个字符: _f_ox → _b_ox
  • 插入 一个新的字符:sic → sic_k_
  • 删除 一个字符:b_l_ack → back

Frederick Damerau 后来在这些操作基础上做了一个扩展:

  • 相邻两个字符的 换位 : _st_ar → _ts_ar

举个例子,将单词 bieber 转换成 beaver 需要下面几个步骤:

  • 把 b 替换成 v :bie_b_er → bie_v_er
  • 把 i 替换成 a :b_i_ever → b_a_ ever
  • 把 e 和 a 进行换位:b_ae_ver → b_ea_ver

这三个步骤表示 Damerau-Levenshtein edit distance 编辑距离为 3 。

显然,从 beaver 转换成 bieber 是一个很长的过程—他们相距甚远而不能视为一个简单的拼写错误。 Damerau 发现 80% 的拼写错误编辑距离为 1 。换句话说, 80% 的拼写错误可以对原始字符串用 单次编辑 进行修正。

Elasticsearch 指定了 fuzziness 参数支持对最大编辑距离的配置,默认为 2 。

当然,单次编辑对字符串的影响取决于字符串的长度。对单词 hat 两次编辑能够产生 mad , 所以对一个只有 3 个字符长度的字符串允许两次编辑显然太多了。 fuzziness 参数可以被设置为 AUTO ,这将导致以下的最大编辑距离:

  • 字符串只有 1 到 2 个字符时是 0
  • 字符串有 3 、 4 或者 5 个字符时是 1
  • 字符串大于 5 个字符时是 2

当然,你可能会发现编辑距离 2 仍然是太多了,返回的结果似乎并不相关。 把最大 fuzziness 设置为 1 ,你可以得到更好的结果和更好的性能。

zero_terms_query

暂不翻译

Cutoff frequency

暂不翻译

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值