搜索请求的基本模块
- query: 具体的搜索内容
- size:返回文档的数量,默认10
- from:偏移量:如果要看第二页的10个结果,ES需要计算出前20个结果->获取靠后的分页代价越来越大,默认0
- _source:指定返回的字段,默认全部字段返回
- sort:排序,默认的排序是按照文档的得分降序排
- profile:分析
- explain:计算得分过程
Search API
- URI Search
- 在 URL 上使用查询参数

- Request Body Search
- 使用 ElasticSearch 提供的,基于 JSON 格式的更加完备的 Query Domain Specific Language (DSL)

响应体解析
{// 花费时间,毫秒"took": 4,// 是否超时"timed_out": false,// 涉及分片信息"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},// 命中文档的信息组"hits": {// 命中数"total": {"value": 1,"relation": "eq"},// 命中文档中最大的匹配分数"max_score": 5.247024,// 命中文档详细信息"hits": [{// 文档索引"_index": "o2srh_o2pcm_platform_product_10_2",// 文档索引类型"_type": "_doc",// 文档id"_id": "hmbb_OW-1",// 此词搜索文档的匹配分数"_score": 5.247024,// 文档源字段"_source": {"platformProductCode": "hmbb","title": "海绵宝宝","stockFlag": 1}}]}}
基于词项和基于全文的搜索
创建索引的Mapping结构
PUT book{"mappings": {"dynamic": "false","properties": {"nameText": {"type": "text","analyzer": "standard"},"nameKeyWord": {"type": "keyword"},"country": {"type": "keyword"},"price": {"type": "float"}}}}
插入的数据
[{"nameText":"ES in action ES","nameKeyWord":"ES in action ES","country":"China","price":100},{"nameText":"ES in one action","nameKeyWord":"ES in one action","country":"Japan","price":200},{"nameText":"ES in one two action","nameKeyWord":"ES in one two action","country":"America","price":300},{"nameText":"What is ES","nameKeyWord":"What is ES","country":"China","price":400},{"nameText":"one thing is good","nameKeyWord":"one thing is good","country":"America","price":500}]
nameText 字段被设置成 text 类型,会走分析流程,并且使用 设置的 standard分析器进行分析写入:
| Term | _id: 1 | _id: 2 | _id: 3 | _id: 4 | _id: 5 |
|---|---|---|---|---|---|
| es | 2 | 1 | 1 | 1 | |
| in | 1 | 1 | 1 | ||
| action | 1 | 1 | 1 | ||
| one | 1 | 1 | 1 | ||
| two | 1 | ||||
| what | 1 | ||||
| is | 1 | 1 | |||
| thing | 1 | ||||
| good | 1 |
基于全文的查询
特点:
- 索引和搜索时都会进行分词,查询字符串先传递到一个合适的分词器,然后生成一个供查询的词项列表
- 查询的时候,先会对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果进行合并。并为每个文档生成一个得分。
典型代表:
- Match Query
- Match Phrase Query
- Match Phrase Prefix
基于 Term 的查询
Term 是分词语义的最小单位。
在 ES 中, Term 查询,对输入不做分词。会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分。
可以利用 Constant Score 将查询转换成一个 Filtering,避免算分,并且利用缓存,提高性能。
典型代表组成:
- Term Query
- Range Query
- Prifix Qery
ES 的两种搜索上下文
- query context:
- 关注点是的是匹配度有多高,并计算出匹配分数,关注点是match
- 查询:计算文档得分
- 结果不会缓存
- 走的是倒排索引
- 应用场景:全文检索以及任何需要相关性的场景
- filter context:
- 关注点是匹配与否,并不需要计算分数,关注点是 included or not
- 只筛选出符合的文档,不算得分
- 缓存文档 ——>大范围筛选数据
- 走的是 Bitsets
- 应用场景:完全精确匹配,范围检索
性能比较
- query context除了检索外,还需要计算相关度
- filter 有缓存
filter context 怎么缓存
- ES 会创建一个文档匹配过滤器的位集 bitset,文档匹配就是1,否则为0,随后用相同的过滤器查询就会重用这部分缓存。
- 当创建/更新文档时,bitset也会更新
Lucene金科玉律:尽量用 filter context,除非必须使用 query context(当且仅当需要计算分的时候)
bool 复合查询
是一个或者多个查询子句的组合。组合查询。
bool:
- query context:
- must:必须匹配。贡献算分
- should:选择性匹配。贡献算分。
- filter context:
- must not:查询字句,必须不能匹配
- filter:必须匹配,但不贡献算分
聚合(Aggregation)
ES 对数据进行统计分析的功能,
经典组成:
- Bucket Aggregation
- 分组,一组满足条件的文档
- Metric Aggregation
- 一系列的统计方法(最大值、最小值、平均值)

