12 搜索之DSL--基础查询
文章目录
- 1 DSL介绍
- 查询和过滤的区别
- 2 数据准备
- 3 文本查询
- 3.1 match 查询
- 3.1.1 查询所有(match_all)
- 3.1.2 match_none
- 3.1.3 match query(匹配查询)
- or
- and
- minimum_should_match 最小匹配参数
- 可以使用通配符: *
- 其他参数
- 3.2 Match Phrase Query(短语查询)
- 词条位置
- 演示
- slop 参数
- 3.3 match_phrase_prefix
- 3.4 multi_match(多字段查询)
- 基本使用
- 加权:可以使用(^)表示法增强各个字段:
- 查询类型(TODO)
- 4 字段查询
- 4.1 单字段查询
- 4.2 多词条精确匹配(terms)
- 4.3 范围查询 (range)
- 入门
- 接受的参数
- 日期匹配
- 入门
- 时间的数学表达
- 关于时间的四舍五入
- 日期格式化
- 指定时区
- 5 其他查询
- 5.1 是否存在查询
- 查询指定字段包含任何非空值的文档
- 查询指定字段包含为空值的文档
- 5.2 前缀查询(prefix)
- 5.3 通配符查询(wildcard)
- 5.4 模糊查询(Fuzziness)
- 什么是模糊搜索?
- 入门
- fuzziness 参数取值规则
- prefix_length 参数
- max_expansions参数
- ID查询
1 DSL介绍
Elasticsearch提供了基于JSON的完整查询DSL(Domain Specific Language)来定义查询。
将查询DSL视为查询的AST(抽象语法树),它由两种子句组成:
叶子查询子句(Leaf query clauses)
在特定字段中查找特定值, 例如match,term或range查询复合查询子句(Compound query clauses)
以逻辑方式组合多个叶子、复合查询为一个查询(例如bool或dis_max查询),
查询和过滤的区别
查询:用于检查内容与条件是否匹配,并且计算_score
元字段表示匹配度。查询的结构中以query参数来开始执行内容的查询。
过滤:不计算匹配得分,只是简单的决定文档是否匹配。过滤往往会被elasticsearch自动缓存起来提高性能。
查询的子句中也可以传递filter参数。
2 数据准备
- 准备一个商品的索引
PUT goods
{"mappings": {"properties": {"id":{"type": "long"},"name":{"type": "text","analyzer": "ik_max_word"},"category":{"type": "keyword"},"price":{"type": "float"},"content":{"type": "text","analyzer": "ik_max_word"},"create_at":{"type": "date","format": ["yyyy-MM-dd hh:mm:ss"]}}}
}
- 插入数据
PUT goods/_doc/1
{"id":1,"name": "苹果手机12","category":"手机","price":8999.00,"content":"Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at":"2020-12-12 12:00:00"}
PUT goods/_doc/2
{"id":2,"name": "华为手机P40","category":"手机","price":7999.00,"content":"华为p40 5G手机 亮黑色 8+128G全网通","create_at":"2020-12-11 12:00:00"}
3 文本查询
基本语法
GET /索引库名/_search
{"query":{"查询类型":{"查询条件":"查询条件值"}}
}
- 查询类型:
- 例如:
match_all
,match
,term
,range
等等
- 例如:
- 查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解
3.1 match 查询
3.1.1 查询所有(match_all)
GET goods/_search
{"query": {"match_all": {}}
}
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}},{"_index" : "goods","_type" : "_doc","_id" : "2","_score" : 1.0,"_source" : {"id" : 2,"name" : "华为手机P40","category" : "手机","price" : 7999.0,"content" : "华为p40 5G手机 亮黑色 8+128G全网通","create_at" : "2020-12-11 12:00:00"}}]}
}
可以不指定索引库:查询所有的索引库
GET _search
{"query": {"match_all": {}}
}
3.1.2 match_none
这是match_all查询的逆函数,该查询不匹配任何文档
3.1.3 match query(匹配查询)
用于执行全文查询的标准查询,包括模糊匹配和短语或接近查询。
match类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系(默认)
or
GET goods/_search?
{"query": {"match": {"content": {"query": "华为手机","operator": "or" # 默认就是or}}}
}
查询结果: 两条记录都查出来了
{"took" : 2,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.96994376,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "2","_score" : 0.96994376,"_source" : {"id" : 2,"name" : "华为手机P40","category" : "手机","price" : 7999.0,"content" : "华为p40 5G手机 亮黑色 8+128G全网通","create_at" : "2020-12-11 12:00:00"}},{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.16613919,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
- 华为手机,经过分词分为:华为,手机
- 搜索的时候,content字段中包含手机,或者华为这两个词就可以被匹配出来
and
GET goods/_search?
{"query": {"match": {"content": {"query": "华为手机","operator": "and"}}}
}
根据上面,这里应该只会查出华为手机
{"took" : 8,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.96994376,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "2","_score" : 0.96994376,"_source" : {"id" : 2,"name" : "华为手机P40","category" : "手机","price" : 7999.0,"content" : "华为p40 5G手机 亮黑色 8+128G全网通","create_at" : "2020-12-11 12:00:00"}}]}
}
minimum_should_match 最小匹配参数
在 or 与 and 间二选一有点过于非黑即白。 如果用户给定的条件分词后有 5 个查询词项,想查找只包含其中 4 个词的文档,该如何处理?将 operator 操作符参数设置成 and 只会将此文档排除,如果是or就会导致搜出的结果和用户的期望值差距较大。所以就引入了minimum_should_match
最小匹配数的参数:
这让我们可以指定必须匹配的词项数用来表示一个文档是否相关。我们可以将其设置为某个具体数字,更常用的做法是将其设置为一个百分数,因为我们无法控制用户搜索时输入的单词数量:
比如:下面这个查询我们指定了最小匹配数为2,所以只会查出华为手机
GET goods/_search?
{"query": {"match": {"content": {"query": "华为手机","operator": "or","minimum_should_match": 2}}}
}
可以使用通配符: *
GET goods/_search
{"query": {"match": {"name": {"query": "p*","operator": "and"}}}
}
{"took" : 148,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.27779984,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "2","_score" : 0.27779984,"_source" : {"id" : 2,"name" : "华为手机P40","category" : "手机","price" : 7999.0,"content" : "华为p40 5G手机 亮黑色 8+128G全网通","create_at" : "2020-12-11 12:00:00"}}]}
}
其他参数
- lenient: 可以设置为true来忽略数据类型匹配出错造成的异常,
不常用
- analyzer: 指定搜索时候使用的分词
eg: 使用标准分词器搜索华为手机
GET goods/_search?
{"query": {"match": {"content": {"query": "华为手机","operator": "or","analyzer": "standard", "minimum_should_match": 2}}}
}
eg: price 是 float 类型的,如果查询 price=2499x ,就会导致无法转换而报错: search_phase_execution_exception
GET goods/_search?
{"query": {"match": {"price": {"query": "8999xx"}}}
}
就可以指定lenient为true来忽略这个错误
GET goods/_search?
{"query": {"match": {"price": {"query": "8999xx","lenient": "true"}}}
}
3.2 Match Phrase Query(短语查询)
match_phrase 查询针对的是一个语句,比如 “like football”, 分析时也会将整个语句作为整体
词条位置
当一个字符串被分析时,分析器不仅只返回一个词条列表,它同时也返回原始字符串的每个词条的位置、或者顺序信息:
POST _analyze
{"analyzer": "ik_max_word","text": "华为手机"
}
{"tokens" : [{"token" : "华为","start_offset" : 0, # 偏移量"end_offset" : 2, # 偏移量"type" : "CN_WORD","position" : 0 # 位置},{"token" : "手机","start_offset" : 2, # 偏移量"end_offset" : 4, # 偏移量"type" : "CN_WORD","position" : 1 # 位置}]
}
像match_phrase这样位置感知(Position-aware)的查询能够使用位置信息来匹配那些含有正确单词出现顺序的文档,且在这些单词之间没有插入别的单词
对于查询华为手机,必须满足:
- 字段中必须含有这两个分词
- 手机的位置必须比华为的位置大于1
演示
请求:查询content字段中时候有移动联通电信
GET goods/_search
{"query": {"match_phrase": {"content": {"query": "移动联通电信","analyzer": "ik_max_word"}}}
}
响应:会查出苹果手机这一条
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 2.526501,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 2.526501,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
如果查询的是移动电信联通
呢,根据前面说的必须要保证联通在电信前面,是不会查出数据的
GET goods/_search
{"query": {"match_phrase": {"content": {"query": "移动电信联通","analyzer": "ik_max_word"}}}
}
{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 0,"relation" : "eq"},"max_score" : null,"hits" : [ ]}
}
默认使用 match_phrase 时会精确匹配查询的短语,需要全部单词和顺序要完全一样,标点符号除外。,所以改了顺序之后就不到了
slop 参数
默认是0
slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配
什么是相隔多远? 意思是说为了让查询和文档匹配你需要移动词条多少次?
比如刚刚的移动电信联通
没有搜索出来,就可以通过这个slop去调整,能够搜索出来
GET goods/_search
{"query": {"match_phrase": {"content": {"query": "移动电信联通","analyzer": "ik_max_word","slop": 3}}}
}
{"took" : 3,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.6871974,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.6871974,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
3.3 match_phrase_prefix
原理跟match_phrase类似,唯一的区别,就是把最后一个term作为前缀去搜索。
比如输入 hello w 进行搜索
- hello就是去进行match,搜索对应的doc
- w,会作为前缀,去扫描整个倒排索引,找到所有w开头的doc
- 然后找到所有doc中,即包含hello,又包含w开头的字符的doc
- 根据你的slop去计算,看在slop范围内,能不能让hello w,正好跟doc中的hello和w开头的单词的position相匹配
- max_expansions:指定prefix最多匹配多少个term,超过这个数量就不继续匹配了,限定性能
默认情况下,前缀要扫描所有的倒排索引中的term,去查找w打头的单词,但是这样性能太差。可以用max_expansions限定,w前缀最多匹配多少个term,就不再继续搜索倒排索引了。
- 尽量不要用,因为,最后一个前缀始终要去扫描大量的索引,性能可能会很差
- max_expansions:指定prefix最多匹配多少个term,超过这个数量就不继续匹配了
可以通过这个去做那种联想搜索。
3.4 multi_match(多字段查询)
multi_match查询以match查询为基础,以允许多字段查询:
基本使用
GET 索引库/_search
{"query": {"multi_match": {"query": "查询关键词","fields": ["字段1","字段2"],"operator": "and" # 默认是or 查询关键词分词之后,是or还是and}}
}
查询关键词:手机12
GET goods/_search
{"query": {"multi_match": {"query": "手机12","fields": ["content","name"],"operator": "and"}}
}
只会查询苹果手机12:因为是and连接,手机12会被分词为苹果和手机
{"took" : 5,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.9752057,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.9752057,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
如果改成or:
GET goods/_search
{"query": {"multi_match": {"query": "手机12","fields": ["content","name"]}}
}
{"took" : 2,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.9752057,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.9752057,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}},{"_index" : "goods","_type" : "_doc","_id" : "2","_score" : 0.20199655,"_source" : {"id" : 2,"name" : "华为手机P40","category" : "手机","price" : 7999.0,"content" : "华为p40 5G手机 亮黑色 8+128G全网通","create_at" : "2020-12-11 12:00:00"}}]}
}
加权:可以使用(^)表示法增强各个字段:
GET /_search
{"query": {"multi_match" : {"query" : "华为手机","fields" : [ "content^3", "name" ] }}
}
content字段是name字段重要三倍
如果未提供任何字段,则multi_match查询默认为index.query.default_field索引设置,而默认设置为。 提取映射中所有符合词条查询条件的字段,并过滤元数据字段。 然后将所有提取的字段组合起来以构建查询。
查询类型(TODO)
多匹配查询内部执行方式取决于:type参数,他的取值有:
- best_fields(默认):查找匹配任何字段的文档,但是使用最佳匹配的
_score
。 - most_fields:查找匹配任何字段的文档,结合每个字段的
_score
。 - cross_fields: 用相同的分词器处理字段,把这些字段当做一个大字段。查找任何字段的每个单词
- phrase:每个字段上进行短语匹配查询(match_phrase),结合每个字段的
_score
。 - phrase_prefix:每个字段上进行短语前缀匹配查询(match_phrase_prefix),结合每个字段的
_score
。
- best_fields: 在同一个字段中,搜索多个单词的时候,此参数最有用,比如一个字段包含
华为手机
,比包含手机
或者包含华为
更有意义,best_fields会对每个字段生成一个匹配查询,并且封装成dis_max
查询,来找到最佳匹配字段,例如:
GET goods/_search
{"query": {"multi_match": {"query": "华为手机","fields": ["name","content"],"type": "best_fields"}}
}
回执行为:
GET goods/_search
{"query": {"dis_max": {"queries": [{"match": {"content": "华为手机"}},{"match": {"name": "华为手机"}}]}}
}
4 字段查询
前面的查询都会先分析查询字符串(进行分词),而字段查询只针对存储在反向索引中的精确索引词。查询关键字不会先进行分词
这些精确值可能是数字、时间、布尔或者那些未分词的字符串
4.1 单字段查询
查询指定字段中包含的指定内容进行查找。
eg: 查询name字段包含苹果手机的
GET goods/_search
{"query": {"term": {"name": "苹果手机"}}
}
- 苹果手机不会被分词,作为一个整体去匹配,name字段中是否包含的苹果手机
这里的查询结果是空!!!!
{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 0,"relation" : "eq"},"max_score" : null,"hits" : [ ]}
}
name为苹果手机12
的那条文档,在倒序索引中,会被ik分词器分词为苹果
,手机
,12
,显然这三个索引词都和我们指定的苹果手机不匹配。说到底就是我们的查询关键字不会先进行分词
4.2 多词条精确匹配(terms)
terms` 查询和 term 查询一样,但它允许你指定多值进行匹配。
GET goods/_search
{"query": {"terms": {"name": ["手机","苹果"]}}
}
4.3 范围查询 (range)
根据指定字段包含的值(日期,数字或字符串等)范围查找文档
入门
查询价格大等于8000的商品
GET goods/_search
{"query": {"range": {"price": {"gte": 8000}}}
}
接受的参数
- gte:大于等于
- gt:大于
- lte:小于等于
- lt:小于
- boots:设置查询的加权值,默认是1.0
日期匹配
入门
GET goods/_search
{"query": {"range": {"create_at": {"gte": "now-d/d" # 当前时间的上一天, 四舍五入到最近的一天"lt": "now-1d/d" # 当前时间, 四舍五入到最近的一天}}}
}
时间的数学表达
Elasticsearch中时间可以表示为now, 也就是系统当前时间, 也可以是以||
结尾的日期字符串表示.
在日期之后, 可以选择一个或多个数学表达式:
表示式 | 含义 |
---|---|
y | 年 |
M | 月 |
w | 周 |
d | 天 |
H | 时 |
m | 分 |
s | 秒 |
eg:
+1h —— 加1小时;
-1d —— 减1天;
/d —— 四舍五入到最近的一天.
/M —— 四舍五入到最近的一天.
说明: 假设系统当前时间now = 2018-10-01 12:00:00 :now+1h
: now的毫秒值 + 1小时, 结果是: 2018-10-01 13:00:00.now-1h
: now的毫秒值 - 1小时, 结果是: 2018-10-01 11:00:00.now-1h/d
: now的毫秒值 - 1小时, 然后四舍五入到最近的一天的起始, 结果是: 2018-10-01 00:00:00.2018.10.01||+1M/d
: 2018-10-01的毫秒值 + 1月, 再四舍五入到最近一天的起始, 结果是: 2018-11-01 00:00:00
关于时间的四舍五入
向上舍入: 移动到舍入范围的最后一毫秒;
向下舍入: 一定到舍入范围的第一毫秒.
- “gt”: “2018-12-18||/M” —— 大于日期, 需要向上舍入, 结果是2018-12-31T23:59:59.999, 也就是不包含整个12月.
- “gte”: “2018-12-18||/M” —— 大于或等于日期, 需要向下舍入, 结果是 2018-12-01, 也就是包含整个12月.
- “lt”: “2018-12-18||/M” —— 小于日期, 需要向上舍入, 结果是2018-12-01, 也就是不包含整个12月.
- “lte”: “2018-12-18||/M” —— 小于或等于日期, 需要向下舍入, 结果是2018-12-31T23:59:59.999, 也就是包含整个12月.
日期格式化
GET goods/_search
{"query": {"range": {"create_at": {"lt": "2021-01-01","format": "yyyy-MM-dd"}}}
}
指定时区
GET goods/_search
{"query": {"range": {"create_at": {"time_zone": "+01:00", "gte": "2020-01-01 00:00:00","format": "yyyy-MM-dd hh:mm:ss"}}}
}
5 其他查询
5.1 是否存在查询
查询指定字段包含任何非空值的文档
查询name字段不为空的商品
GET goods/_search
{"query": {"exists": {"field": "name"}}
}
name为空的情况:
- null
- [] (空数组)
- [null]
- 没有name字段的文档
查询指定字段包含为空值的文档
上一个的逆操作
GET goods/_search
{"query": {"bool": {"must_not": [{"exists": {"field": "name"}}]}}
}
5.2 前缀查询(prefix)
查询字段包含指定前缀的索引词(不分词)。
插叙name字段前缀为华为的商品
GET goods/_search
{"query": {"prefix": {"name": {"value": "华为"}}}
}
5.3 通配符查询(wildcard)
注意的是这个查询会比较慢,需要在多个索引词上面重复执行。为了避免极端缓慢的查询,应该避免查询的时使用通配符开头
*:匹配任意字符(包含空字符)
?:匹配任意单个字符
GET goods/_search
{"query": {"wildcard": {"name": "华为?" }}
}
5.4 模糊查询(Fuzziness)
fuzzniess 参数可以使查询的字段具有模糊搜索的特性。来先了解下什么是模糊搜索。
什么是模糊搜索?
模糊搜索是指系统允许被搜索信息和搜索提问之间存在一定的差异,这种差异就是“模糊”在搜索中的含义。例如,查找名字Smith时,就会找出与之相似的Smithe, Smythe, Smyth, Smitt等。(百度百科)
通过模糊搜索可以查询出存在一定相似度的单词,那么怎么计算两个单词是否有相似度以及相似度的大小呢?这就要了解下另外一个概念:Levenshtein Edit Distance
Levenshtein Edit Distance 叫做莱文斯坦距离,是编辑距离的一种。指两个字串之间,由一个转成另一个所需的最少编辑操作次数。允许的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如,单词 “god” 只需要插入一个 ‘o’ 字符就可以变为 “good”,因此它们之间的编辑距离为 1。
入门
- 查询ipone
GET goods/_search
{"query": {"match": {"content": {"query": "ipone"}}}
}
没有查到结果
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 0,"relation" : "eq"},"max_score" : null,"hits" : [ ]}
}
- 执行下面的查询,便可模糊查出结果
GET goods/_search
{"query": {"match": {"content": {"query": "ipone","fuzziness": 1}}}
}
{"took" : 39,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.5053002,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.5053002,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
或者
GET goods/_search
{"query": {"fuzzy": {"content": {"value": "ipone","fuzziness": 1}}}
}
{"took" : 5,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.5053002,"hits" : [{"_index" : "goods","_type" : "_doc","_id" : "1","_score" : 0.5053002,"_source" : {"id" : 1,"name" : "苹果手机12","category" : "手机","price" : 8999.0,"content" : "Apple iPhone 12 Pro Max (A2412) 256GB 海蓝色 支持移动联通电信5G 双卡双待手机","create_at" : "2020-12-12 12:00:00"}}]}
}
fuzziness 参数取值规则
在查询 text 或者 keyword 类型的字段时, fuzziness 可以看做是莱文斯坦距离。
fuzziness 参数的取值如下
- 0,1,2: 表示最大可允许的莱文斯坦距离
- auto:
会根据词项的长度来产生可编辑距离,它还有两个可选参数,形式为AUTO:[low],[high], 分别表示短距离参数和长距离参数;如果没有指定,默认值是 AUTO:3,6 表示的意义如下- 0…2 单词长度为 0 到 2 之间时必须要精确匹配,这其实很好理解,单词长度太短是没有相似度可言的,例如 ‘a’ 和 ‘b’。
- 3…5: 单词长度 3 到 5 个字母时,最大编辑距离为 1
5: 单词长度大于 5 个字母时,最大编辑距离为 2
如果不设置 fuziness 参数,查询是精确匹配的。
fuzziness 在绝大多数场合都应该设置成 AUTO(来自官网)
对在中文环境下Fuzziness这个模糊查询的没有什么意义,
prefix_length 参数
prefix_length 表示不能没模糊化的初始字符数。由于大部分的拼写错误发生在词的结尾,而不是词的开始,使用 prefix_length 就可以完成优化。注意 prefix_length 必须结合 fuzziness 参数使用。默认0
prefix_length设置3,前三个字母就不能模糊化,所以这里ihpone不会匹配到数据
GET goods/_search
{"query": {"fuzzy": {"content": {"value": "ihpone","fuzziness": 1,"prefix_length": 3}}}
}
或者
GET goods/_search
{"query": {"match": {"content": {"query": "ihpone","fuzziness": 1,"prefix_length": 3}}}
}
max_expansions参数
模糊查询将要扩展的索引词最大数量,默认50
ID查询
GET goods/_search
{"query": {"ids": {"type": "_doc", "values": [1,2]}}
}
在老版本,es还没有取消的type的时候,请求是上面这样的,后来取消type了 (Deprecation: [types removal] Types are deprecated in [ids] queries.)
GET goods/_search
{"query": {"ids": {"values": [1,2]}}
}
12 搜索之DSL--基础查询相关推荐
- 大工17春计算机基础,大工12春《计算机应用基础》在线测试3答案
<大工12春<计算机应用基础>在线测试3答案>由会员分享,可在线阅读,更多相关<大工12春<计算机应用基础>在线测试3答案(5页珍藏版)>请在人人文库网 ...
- day01 与MySQL的第一次亲密接触基础查询条件查询
<尚硅谷>MySQL系统课程一共6天,下面介绍第1天的学习内容,主要涉及MySQL的内容介绍.进阶1基础查询和进阶2条件查询.干货满满,跟着课程的进度来的,可能篇幅略长,但是看完一定会有收 ...
- Day121.ElasticSearch:概述、安装、基本操作、DSL高级查询
目录 一.ElasticSearch概述 2.倒排索引 3.ElasticSearch 核心概念 ★ (一) ElasticSearch | 相关工具安装 (Windows) 2.kibana7.8 ...
- 微服务11_ES:DSL/RestClient查询文档
微服务11_ES:DSL/RestClient查询文档 一.DSL查询文档 1.DSL Query的分类 1.全文检索查询 match查询示例: multi_match查询示例: 2.精准查询 ter ...
- Elasticsearch Query DSL基础介绍
查询语法(Query DSL) Elasticsearch提供标准RESTful风格的查询DSL来定义查询.可以将查询 DSL 看作是由两种子句组成的查询的 AST (Abstract Syntax ...
- 【SQL】SQL(基础查询)、SQL(关联查询)
原文链接:https://blog.csdn.net/kuangzhixuan/article/details/74299047?utm_source=blogxgwz2 SQL(基础查询) 1.1. ...
- SQL语法之基础查询(进阶1)and条件查询(进阶2)
SQL语法体系学习笔记 SQL语法之基础查询(进阶1)and条件查询(进阶2) SQL语法之排序查询(进阶3)and常见函数(进阶4) SQL语法之分组函数,分组查询(进阶5)and连接查询(sql9 ...
- 查询去重_【Freya的MySQL课堂】DQL基础查询
MYSQL 基础查询 各位小伙伴们晚上好,今天是10月22号. 我是你们的Freya. 今天我们开始学习MySQL中的DQL语言. Do Not Stop Learning 我 的 小 课 堂 我爱学 ...
- 一、MySQL查询学习笔记(基础查询、条件查询、排序查询、常见函数、分组查询 详解)
DQL语言的学习 一.基础查询 语法: **SELECT 要查询的东西 [FROM 表名];**类似于Java中 :System.out.println(要打印的东西); 特点: ①通过select查 ...
最新文章
- python中赋值不正确的_python中的“赋值与深浅拷贝”
- 解决tensorflow报错:AttributeError: module ‘tensorflow.keras.backend‘ has no attribute ‘get_session‘ 问题
- 研究人员开发出最节能的 Wi-Fi 技术
- mof格式的文件怎么打开?用什么工具?
- Java项目构建基础的三个统一,太厉害了!
- C++中const用于函数重载
- STM32 (Cortex-M3) 中NVIC(嵌套向量中断控制)的理解
- centos php fpm 停止_如何关闭php-fpm进程?
- 全数字实时仿真平台SkyEye故障注入测试
- java根据xsd验证json文件_JSON解析器之json schema校验及代码实现
- java比较时间大小
- NAS自回血方案介绍
- C# 群发邮件 (密送、抄送)
- 3d抽奖html,3d抽奖(微信)
- Linux数据备份工具
- 从github下载laravel项目碰到的坑
- windows phone 7---8 Belling's课堂(十五) 程序等待页面的处理
- AD快捷键、常见问题汇总
- 每日新闻早报简报 资讯12条 新闻早知道
- 揭秘!杀毒软件公司的诱捕蜜罐
热门文章
- ILog项目开发流程【一】
- 【Rust】argh:基于 derive 宏且对二进制体积进行优化的命令行解析工具
- [升级][报错]zipimport.ZipImportError: can‘t decompress data; zlib not available
- mac电脑开机是出现安全启动
- 塑料壳上下扣合的卡扣设计_读书笔记-塑胶外壳卡扣设计
- linux mate主题目录,七大顶级Linux桌面:Cinnamon和MATE_服务器_服务器产业-中关村在线...
- mysql uuid分页优化_MySQL性能优化之分页查询优化
- Hadoop 安全模式永久退出的方法
- macos esc按键失效,无法退出vim
- Android延时执行事件的方法