概述
查询上下文
使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。搜索是ES最关键和重要的部分。
相关度评分:_score
概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符号预期值。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认使用BM25。
排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前。
元数据:_source
- 禁用_source:
- 好处:节省存储开销。
- 坏处:
- 不支持update、update_by_query和reindex API。
- 不支持高亮。
- 不支持reindex、更改mapping分析器和版本升级。
- 通过查看索引时使用的原始文档来调试查询或聚合的功能。
- 将来有可能自动修复索引损坏。
总结:如果只是为了节省磁盘,可以采用压缩索引比禁用_source更好。
- 数据源过滤器
including:结果中返回哪些field
excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在。- 在mapping中定义过滤,支持通配符,但是这种方式不推荐,因为mapping不可变。
PUT product
{
"mappings": {
"_source": {
"includes": [
"name",
"price"
],
"excludes": [
"desc",
"tags"
]
}
}
}
- 常用过滤规则
- “_source”:“false”
- “_source”:“obj.*”
- “_source”:[“obj1.*”,“xxx”],
- “_source”:{
“includes”: [“field1”,“field2”],
“excludes”:[“xxx”,“xxx”]
}
Query String
- 查询所有
GET /product/_search
- 带参数
GET /product/_search?q=name:xiaomi
- 分页
- GET /product/_search?from=0&size=2&sort=price:asc
- 精准匹配 exact value
GET /product/_search?q=date:2021-06-01
- _all 搜索 相当于在所有有索引的字段中检索
GET /product/_search?q=2021-06-01
全文检索-fulltext query
语法:
GET index/_search
{
"query": {
***
}
}
match:匹配包含某个term(词项)的子句,相对mysql中的模糊匹配
下面示例中”xiaomi nfc phone” 会被拆分成3个词项,满足任何一个词项的doc,都会被搜索出来。
GET /product/_search
{
"query": {
"match": {
"name": "xiaomi nfc phone"
}
}
}
match_all:匹配所有结果的子句
GET /product/_search
{
"query": {
"match_all": {}
}
}
multi_match:多字段条件
在多个字段中查询,一个字段中包含查询条件就搜索出,match只是在一个字段中查询。
GET /product/_search
{
"query": {
"multi_match": {
"query": "phone",
"fields": ["name", "desc"]
}
}
}
match_phrase:短语查询
查询的字段中必须包含该短语。
GET /product/_search
{
"query": {
"match_phrase": {
"name": "xiaomi nfc"
}
}
}
精准查询
term:匹配和搜索词项完全相等的结果
也就是搜索的字段中必须包含指定的词项,且term指定的就是完整的词项,不会向match那样进行拆分。
GET /product/_search
{
"query": {
"term": {
"name": {
"value": "nfc"
}
}
}
}
- term和match_phrase区别:
match_phrase会将检索关键词分词,match_phrase的分词结果必须被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是联系的。
term搜索不会将搜索词分词。 - term和keyword区别
term是对于搜索词不分词。
keyword是字段类型,是对于source data中的字段不分词,是一个完整的词项。
GET /product/_search
{
"query": {
"term": {
"name.keyword": {
"value": "xiaomi nfc phone"
}
}
}
}
terms:匹配和搜索词项列表中任意项匹配的结果
term是搜索字段包含其中的词项即可,terms是指搜索字段中只要包含其中的一个词项即可,也就是terms中可以包含多个词项。
GET /product/_search
{
"query": {
"terms": {
"name": [
"phone",
"xiaomi"
]
}
}
}
range:范围查找
GET /product/_search
{
"query": {
"range": {
"price": {
"gte": 1000,
"lte": 50000
}
}
}
}
filter 查询
filter查询的性能比query要高,主要原因是filter查询对结果不在进行评分,减少了评分所消耗的时间。
示例如下:
// 给定具体的评分,不给定默认是1分
GET /product/_search
{
"query": {
"constant_score": {
"filter": {
"match": {
"name": "huawei"
}
}
"boost":1
}
}
}
// 放在组合查询中
GET /product/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"name": "huawei"
}
}
]
}
}
}
filter与query的主要区别
filter是结果导向的,速度更快,而query是过程导向的。
query倾向于“当前文档和查询的语句的相关度”,而filter倾向于“当前文档和查询到条件是不是相符”。即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。另外filter有相应的缓存机制,可以提高查询效率。
组合查询-Bool query
bool:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,bool组合的条件之间通过and结合起来。
因此满足must和should子句的文档会合并起来计算分值。
- must:必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。
- filter:过滤器,不计算相关度分数,子句(查询)必须出现在匹配的文档中,与must类似。但是不像must查询那样计算分数。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
- should:可能满足,相当于or子句(查询)满足其中一个条件即可查询出匹配的文档。
- must_not:必须不满足,不计算相关度分数,not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,因此所以匹配的文档分数都是0。
- minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或filter子句,则默认为1,否则,默认值为0。
GET /product/_search
{
"query": {
"bool": {
"filter": [
{
"match":{
"name": "phone"
}
}
],
"should": [
{
"match_phrase": {
"name": "xiaomi phone"
}
}
],
"minimum_should_match": 1
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99927.html