文章目录

  • 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 数据准备

  1. 准备一个商品的索引
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"]}}}
}
  1. 插入数据
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_allmatchtermrange 等等
  • 查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解

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 进行搜索

  1. hello就是去进行match,搜索对应的doc
  2. w,会作为前缀,去扫描整个倒排索引,找到所有w开头的doc
  3. 然后找到所有doc中,即包含hello,又包含w开头的字符的doc
  4. 根据你的slop去计算,看在slop范围内,能不能让hello w,正好跟doc中的hello和w开头的单词的position相匹配
  5. 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
  1. 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": "苹果手机"}}
}
  1. 苹果手机不会被分词,作为一个整体去匹配,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。

入门

  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" : [ ]}
}
  1. 执行下面的查询,便可模糊查出结果
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--基础查询相关推荐

  1. 大工17春计算机基础,大工12春《计算机应用基础》在线测试3答案

    <大工12春<计算机应用基础>在线测试3答案>由会员分享,可在线阅读,更多相关<大工12春<计算机应用基础>在线测试3答案(5页珍藏版)>请在人人文库网 ...

  2. day01 与MySQL的第一次亲密接触基础查询条件查询

    <尚硅谷>MySQL系统课程一共6天,下面介绍第1天的学习内容,主要涉及MySQL的内容介绍.进阶1基础查询和进阶2条件查询.干货满满,跟着课程的进度来的,可能篇幅略长,但是看完一定会有收 ...

  3. Day121.ElasticSearch:概述、安装、基本操作、DSL高级查询

    目录 一.ElasticSearch概述 2.倒排索引 3.ElasticSearch 核心概念 ★ (一) ElasticSearch | 相关工具安装 (Windows) 2.kibana7.8 ...

  4. 微服务11_ES:DSL/RestClient查询文档

    微服务11_ES:DSL/RestClient查询文档 一.DSL查询文档 1.DSL Query的分类 1.全文检索查询 match查询示例: multi_match查询示例: 2.精准查询 ter ...

  5. Elasticsearch Query DSL基础介绍

    查询语法(Query DSL) Elasticsearch提供标准RESTful风格的查询DSL来定义查询.可以将查询 DSL 看作是由两种子句组成的查询的 AST (Abstract Syntax ...

  6. 【SQL】SQL(基础查询)、SQL(关联查询)

    原文链接:https://blog.csdn.net/kuangzhixuan/article/details/74299047?utm_source=blogxgwz2 SQL(基础查询) 1.1. ...

  7. SQL语法之基础查询(进阶1)and条件查询(进阶2)

    SQL语法体系学习笔记 SQL语法之基础查询(进阶1)and条件查询(进阶2) SQL语法之排序查询(进阶3)and常见函数(进阶4) SQL语法之分组函数,分组查询(进阶5)and连接查询(sql9 ...

  8. 查询去重_【Freya的MySQL课堂】DQL基础查询

    MYSQL 基础查询 各位小伙伴们晚上好,今天是10月22号. 我是你们的Freya. 今天我们开始学习MySQL中的DQL语言. Do Not Stop Learning 我 的 小 课 堂 我爱学 ...

  9. 一、MySQL查询学习笔记(基础查询、条件查询、排序查询、常见函数、分组查询 详解)

    DQL语言的学习 一.基础查询 语法: **SELECT 要查询的东西 [FROM 表名];**类似于Java中 :System.out.println(要打印的东西); 特点: ①通过select查 ...

最新文章

  1. python中赋值不正确的_python中的“赋值与深浅拷贝”
  2. 解决tensorflow报错:AttributeError: module ‘tensorflow.keras.backend‘ has no attribute ‘get_session‘ 问题
  3. 研究人员开发出最节能的 Wi-Fi 技术
  4. mof格式的文件怎么打开?用什么工具?
  5. Java项目构建基础的三个统一,太厉害了!
  6. C++中const用于函数重载
  7. STM32 (Cortex-M3) 中NVIC(嵌套向量中断控制)的理解
  8. centos php fpm 停止_如何关闭php-fpm进程?
  9. 全数字实时仿真平台SkyEye故障注入测试
  10. java根据xsd验证json文件_JSON解析器之json schema校验及代码实现
  11. java比较时间大小
  12. NAS自回血方案介绍
  13. C# 群发邮件 (密送、抄送)
  14. 3d抽奖html,3d抽奖(微信)
  15. Linux数据备份工具
  16. 从github下载laravel项目碰到的坑
  17. windows phone 7---8 Belling's课堂(十五) 程序等待页面的处理
  18. AD快捷键、常见问题汇总
  19. 每日新闻早报简报 资讯12条 新闻早知道
  20. 揭秘!杀毒软件公司的诱捕蜜罐

热门文章

  1. ILog项目开发流程【一】
  2. 【Rust】argh:基于 derive 宏且对二进制体积进行优化的命令行解析工具
  3. [升级][报错]zipimport.ZipImportError: can‘t decompress data; zlib not available
  4. mac电脑开机是出现安全启动
  5. 塑料壳上下扣合的卡扣设计_读书笔记-塑胶外壳卡扣设计
  6. linux mate主题目录,七大顶级Linux桌面:Cinnamon和MATE_服务器_服务器产业-中关村在线...
  7. mysql uuid分页优化_MySQL性能优化之分页查询优化
  8. Hadoop 安全模式永久退出的方法
  9. macos esc按键失效,无法退出vim
  10. Android延时执行事件的方法