es深入搜索之部分匹配

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es深入搜索之部分匹配相关的知识,希望对你有一定的参考价值。

参考技术A   之前讲的搜索都是针对整个搜索词的操作,只能查找倒排索引的单个词,词是最小单元,但是如果我们想寻找词的部分匹配,比如 sql 语句中的 " %value % " ,es是如何做到的呢?
  在有些情况,也是部分匹配是非常有用的,比如在搜索时的自动提示、比如某些特定的不会分词的字符,邮编,产品序列号等,我们不知道全部字符,只知道该字符串的部分,该如何检索?

  为了找到所有以 W1 开始的邮编,可以使用简单的 prefix 查询:

  prefix查询并不会分析查询词,他只是会在倒排索引的词项列表中,搜索所有的词项,判断是否是以查询词作为前缀。
  注意:
  1. prefix查询并不会计算评分,所有文档评分默认为 1 ,相比较prefix过滤的不同,过滤会缓存,但是查询不会。
  2. prefix查询会对给集群的带来很大压力,如果字段中词的集合很小时,可以放心使用,否则应该使用较长的前缀来限制这些影响。

  与 prefix 前缀查询的特性类似, wildcard 通配符查询也是一种底层基于词的查询,与前缀查询不同的是它允许指定匹配的正则式。它使用标准的 shell 通配符查询: ? 匹配任意字符, * 匹配 0 或多个字符。

  wildcard 和 regexp 查询的工作方式与 prefix 查询完全一样,它们也需要扫描倒排索引中的词列表才能找到所有匹配的词,意味着同样需要注意和前缀查询相同的性能问题。

  类似于淘宝,在我们输入搜索词时,它会在搜索框下展现出搜索结果供用户选择,可以使用户在更短时间内得到搜索结果。
  对于查询时的输入即搜索,可以使用 match_phrase 的一种特殊形式, match_phrase_prefix 查询:

  对于以上查询,会返回 ' 麻辣小龙虾' , ' 麻辣烫 ', ' 麻辣小零食 ' 等以搜索词作为前缀的搜索结果。这种查询的行为与 match_phrase 查询一致,不同的是它将查询字符串的最后一个词作为前缀使用。同样它也支持 slop 参数,让相对位置不那么严格。
  在上边的前缀搜索时,我们谈过使用前缀搜索的问题,在这里问题同样存在,也就是资源消耗问题,如果我们搜索a,索引中有成千上万个以 a 为前缀的文档,这样不仅会消耗系统资源,而且结果的用户也不大。
  可以通过设置 max_expansions 参数来限制前缀扩展的影响, 该参数会设置es查询返回的文档的数量不超过该参数的值。

ES6之解构

1、ES6允许按照一定的模式,从数组中和对象中提取值,对变量进行赋值,这种称为解构(Distructuring);

let [a,b,c] = [3,5,6];// 相当于 a=3,b=5,c=6

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于 undefined

另一种情况是不完全能解构,即等号左边的模式,只匹配一部分等号右边的数组。这种情况下,解构依然可以成功。

2、数组的解构赋值

完全解构:

let [a,b,c] = [6,7,8]; // a=6,b=7,c=8

不完全解构

let [a,[b],c] = [2,[4,6],7];  // a=2,b=4,c=7

集合解构:

let [head,...tail] = [1,3,4,5,6];  // head= 1,tail=[3,4,5,6]

可设置默认值(默认值也可以是函数):

let [x,y=‘b‘]=[‘a‘];   //x=a,y=b

3、对象解构赋值

①解构变量名必须存在于对象属性中,这样才能取到值;

let name,age=name:‘zjl‘,age:18 //name=‘zjl‘,age=18  注意:左侧变量名必须在对象属性名中

②如果变量名与属性名不一致,必须写成下面这样,重命名

let name:username,age=name:‘zjl‘,age:18   // username=‘zjl‘,age=18

③根据第二点可知,解构赋值是以下方式的简写

let name:name,age:age=name:‘zjl‘,age:18   //所以当对象属性名和属性值相等时可以简写

④ 嵌套解构

let p:[x,y]=p:[‘hello‘,y:‘world‘] // x=hello,y=world

⑤对象 解构也可以设置默认值

let x:y=9=10   //y=9

4、字符串的解构赋值

①解构时,字符串被转换成一个类似数组的对象。

const [a,b,c]=‘zjl‘   // a=‘z‘,b=‘j‘,c=‘l‘

②对字符串的length属性进行解构

let length=‘hello‘   //length=5

5、数组和布尔值解构赋值

解构时,如果等号右边是数值和布尔值,则会先转为对象

let toString: s = 123; //函数 s === Number.prototype.toString true
let toString: s = true; //函数 s === Boolean.prototype.toString true

6、解构赋值的用途

① 交换变量的值

let x = 1; let y = 2; [x, y] = [y, x];

②函数返回值

function example()  return [1, 2, 3]; 
let [a, b, c] = example();

③函数参数的定义

function f([x, y, z])  ... 
f([1, 2, 3]);

④模块的按需导入  导入指定的值

 

以上是关于es深入搜索之部分匹配的主要内容,如果未能解决你的问题,请参考以下文章

搜索-意图识别

《深入理解ES6》之解构

ES6之解构

三剑客之grep

ES搜索结果中各个字段介绍

数据结构与算法之深入解析“正则表达式匹配”的求解思路与算法示例