教资注册网站,广告传媒建设网站,wordpress app模板,网络营销编辑干什么的目录
前言:DSL 介绍
一、DSL 简单用法
二、query 和 filter 差异
三、多搜索条件组合查询#xff08;最常用#xff09; 前言:DSL 介绍 这个才是实际最常用的方式#xff0c;可以构建复杂的查询条件。 不用一开始就想着怎样用 Java Client 端去调用 Elasticsearch 接口…目录
前言:DSL 介绍
一、DSL 简单用法
二、query 和 filter 差异
三、多搜索条件组合查询最常用 前言:DSL 介绍 这个才是实际最常用的方式可以构建复杂的查询条件。 不用一开始就想着怎样用 Java Client 端去调用 Elasticsearch 接口。DSL 会了Client 的也只是用法问题而已。
一、DSL 简单用法 查询所有的商品
GET /product_index/product/_search
{query: {match_all: {}}
} 查询商品名称包含 toothbrush 的商品同时按照价格降序排序
GET /product_index/product/_search
{query: {match: {product_name: toothbrush}},sort: [{price: desc}]
} 分页查询商品
GET /product_index/product/_search
{query: {match_all: {}},from: 0, ## 从第几个商品开始查最开始是 0size: 1 ## 要查几个结果
} 指定查询结果字段field
GET /product_index/product/_search
{query: {match_all: {}},_source: [product_name,price]
} 相关符号标识官网Range query | Elasticsearch Guide [8.1] | Elastic 符号标识 代表含义 gte大于或等于gt大于lte小于或等于lt小于 搜索商品名称包含 toothbrush而且售价大于 400 元小于 700 的商品
GET /product_index/product/_search
{query: {bool: {must: {match: {product_name: toothbrush}},filter: {range: {price: {gt: 400,lt: 700}}}}}
} full-text search 全文检索倒排索引 索引中只要有任意一个匹配拆分后词就可以出现在结果中只是匹配度越高的排越前面 比如查询PHILIPS toothbrush会被拆分成两个单词PHILIPS 和 toothbrush。只要索引中 product_name 中只要含有任意对应单词都会在搜索结果中只是如果有数据同时含有这两个单词则排序在前面。
GET /product_index/product/_search
{query: {match: {product_name: PHILIPS toothbrush}}
} phrase search 短语搜索 索引中必须同时匹配拆分后词就可以出现在结果中 比如查询PHILIPS toothbrush会被拆分成两个单词PHILIPS 和 toothbrush。索引中必须有同时有这两个单词的才会在结果中。
GET /product_index/product/_search
{query: {match_phrase: {product_name: PHILIPS toothbrush}}
} Highlight Search 高亮搜索 给匹配拆分后的查询词增加高亮的 html 标签比如这样的结果emPHILIPS/em emtoothbrush/em HX6730/02
GET /product_index/product/_search
{query: {match: {product_name: PHILIPS toothbrush}},highlight: {fields: {product_name: {}}}
} range 用法查询数值、时间区间
GET /product_index/product/_search
{query: {range: {price: {gte: 30.00}}}
} match 用法与 term 进行对比 查询的字段内容是进行分词处理的只要分词的单词结果中在数据中有满足任意的分词结果都会被查询出来
GET /product_index/product/_search
{query: {match: {product_name: PHILIPS toothbrush}}
} match 还有一种情况就是必须满足分词结果中所有的词而不是像上面任意一个就可以的。这个常见所以很重要 看下面的 JSON 其实你也可以猜出来其实上面的 JSON 和下面的 JSON 本质是operator 的差别上面是 or下面是 and 关系。
GET /product_index/product/_search
{query: {match: {product_name: {query: PHILIPS toothbrush,operator: and}}}
} match 还还有一种情况就是必须满足分词结果中百分比的词比如搜索词被分成这样子java 程序员 书 推荐这里就有 4 个词假如要求 50% 命中其中两个词就返回我们可以这样 当然这种需求也可以用 must、must_not、should 匹配同一个字段进行组合来查询
GET /product_index/product/_search
{query: {match: {product_name: {query: java 程序员 书 推荐,minimum_should_match: 50%}}}
} multi_match 用法 查询 product_name 和 product_desc 字段中只要有toothbrush 关键字的就查询出来。
GET /product_index/product/_search
{query: {multi_match: {query: toothbrush,fields: [product_name,product_desc]}}
} multi_match 跨多个 field 查询表示查询分词必须出现在相同字段中。
GET /product_index/product/_search
{query: {multi_match: {query: PHILIPS toothbrush,type: cross_fields,operator: and,fields: [product_name,product_desc]}}
} match_phrase 用法短语搜索与 match 进行对比 对这个查询词不进行分词必须完全匹配查询词才可以作为结果显示。
GET /product_index/product/_search
{query: {match_phrase: {product_name: PHILIPS toothbrush}}
} match_phrase slop与 match_phrase 进行对比 在说 slop 的用法之前需要先说明原数据是PHILIPS toothbrush HX6730/02被分词后至少有PHILIPStoothbrushHX6730 三个 term。 match_phrase 的用法我们上面说了按理说查询的词必须完全匹配才能查询到PHILIPS HX6730 很明显是不完全匹配的。 但是有时候我们就是要这种不完全匹配只要求他们尽可能靠谱中间有几个单词是没啥问题的那就可以用到 slop。slop 2 表示中间如果间隔 2 个单词以内也算是匹配的结果。 其实也不能称作间隔应该说是移位查询的关键字分词后移动多少位可以跟 doc 内容匹配移动的次数就是 slop。所以 HX6730 PHILIPS 其实也是可以匹配到 doc 的只是 slop 5 才行。
GET /product_index/product/_search
{query: {match_phrase: {product_name : {query : PHILIPS HX6730,slop : 1}}}
} match match_phrase slop 组合查询使查询结果更加精准和结果更多 但是 match_phrase 性能没有 match 好所以一般需要先用 match 第一步进行过滤然后在用 match_phrase 进行进一步匹配并且重新打分这里又用到了rescorewindow_size 表示对前 10 个进行重新打分 下面第一个是未重新打分的第二个是重新打分的
GET /product_index/product/_search
{query: {bool: {must: {match: {product_name: {query: PHILIPS HX6730}}},should: {match_phrase: {product_name: {query: PHILIPS HX6730,slop: 10}}}}}
}GET /product_index/product/_search
{query: {match: {product_name: PHILIPS HX6730}},rescore: {window_size: 10,query: {rescore_query: {match_phrase: {product_name: {query: PHILIPS HX6730,slop: 10}}}}}
} match_phrase_prefix 用法不常用一般用于类似 Google 搜索框关键字输入推荐 max_expansions 用来限定最多匹配多少个 term优化性能 但是总体来说性能还是很差因为还是会扫描整个倒排索引。推荐用 edge_ngram 做该功能
GET /product_index/product/_search
{query: {match_phrase_prefix: {product_name: PHILIPS HX,slop: 5,max_expansions: 20}}
} term 用法与 match 进行对比term 一般用在不分词字段上的因为它是完全匹配查询如果要查询的字段是分词字段就会被拆分成各种分词结果和完全查询的内容就对应不上了。 所以自己设置 mapping 的时候有些不分词的时候就最好设置不分词。 其实 Elasticsearch 5.X 之后给 text 类型的分词字段又默认新增了一个子字段 keyword这个字段的类型就是 keyword是不分词的默认保留 256 个字符。假设 product_name 是分词字段那有一个 product_name.keyword 是不分词的字段也可以用这个子字段来做完全匹配查询。
GET /product_index/product/_search
{query: {term: {product_name: PHILIPS toothbrush}}
}GET /product_index/product/_search
{query: {constant_score: {filter:{term: {product_name: PHILIPS toothbrush}}}}
}
GET /product_index/product/_search
{query: {constant_score: {filter: {terms: {product_name: [toothbrush,shell]}}}}
}
二、query 和 filter 差异 只用 query
GET /product_index/_search
{query: {bool: {must: [{terms: {product_name: [PHILIPS,toothbrush]}},{range: {price: {gt: 12.00}}}]}}
} 只用 filter 下面语句使用了 constant_score 查询它可以包含查询或过滤为任意一个匹配的文档指定评分 1 忽略 TF/IDF 信息不需再计算评分。 也还可以指定分数忽略 TF/IDF | Elasticsearch: 权威指南 | Elastic
GET /product_index/product/_search
{query: {constant_score: {filter: {range: {price: {gte: 30.00}}}}}
} query 和 filter 一起使用的话filter 会先执行看本文下面的多搜索条件组合查询 官网文档Queries and Filters | Elasticsearch: The Definitive Guide [2.x] | Elastic 从搜索结果上看 filter只查询出搜索条件的数据不计算相关度分数 query查询出搜索条件的数据并计算相关度分数按照分数进行倒序排序 从性能上看 filter性能更好无排序无需计算相关度分数也就无需排序内置的自动缓存最常使用查询结果的数据 缓存的东西不是文档内容而是 bitset具体看Finding Exact Values | Elasticsearch: The Definitive Guide [2.x] | Elastic query性能较差有排序要计算相关度分数按照分数进行倒序排序没有缓存结果的功能 filter 和 query 一起使用可以兼顾两者的特性所以看你业务需求 三、多搜索条件组合查询最常用 bool 下包括must必须匹配类似于数据库的 must_not必须不匹配类似于数据库的 !should没有强制匹配类似于数据库的 orfilter过滤
GET /product_index/product/_search
{query: {bool: {must: [{match: {product_name: PHILIPS toothbrush}}],should: [{match: {product_desc: 刷头}}],must_not: [{match: {product_name: HX6730}}],filter: {range: {price: {gte: 33.00}}}}}
}GET /product_index/product/_search
{query: {bool: {should: [{term: {product_name: 飞利浦}},{bool: {must: [{term: {product_desc: 刷头},term: {price: 30}}]}}]}}
} should 有一个特殊性如果组合查询中没有 must 条件那么 should 中必须至少匹配一个。我们也还可以通过 minimum_should_match 来限制它匹配更多个。
GET /product_index/product/_search
{query: {bool: {should: [{match: {product_name: java}},{match: {product_name: 程序员}},{match: {product_name: 书}},{match: {product_name: 推荐}}],minimum_should_match: 3}}
} 下面还用到自定义排序。 排序最好别用到字符串字段上。因为字符串字段会进行分词Elasticsearch 默认是拿分词后的某个词去进行排序排序结果往往跟我们想象的不一样。解决这个办法是在设置 mapping 的时候多个这个字段设置一个 fields raw让这个不进行分词然后查询排序的时候使用这个 raw具体看这里字符串排序与多字段 | Elasticsearch: 权威指南 | Elastic
GET /product_index/product/_search
{query: {bool: {must: [{match: {product_name: PHILIPS toothbrush}}],should: [{match: {product_desc: 刷头}}],filter: {bool: {must: [{range: {price: {gte: 33.00}}},{range: {price: {lte: 555.55}}}],must_not: [{term: {product_name: HX6730}}]}}}},sort: [{price: {order: desc}}]
} boost 用法默认是 1。在搜索精准度的控制上还有一种需求比如搜索PHILIPS toothbrush要比Braun toothbrush 更加优先我们可以这样
GET /product_index/product/_search
{query: {bool: {must: [{match: {product_name: toothbrush}}],should: [{match: {product_name: {query: PHILIPS,boost: 4}}},{match: {product_name: {query: Braun,boost: 3}}}]}}
} dis_max 用法也称作best fields 策略。 由于查询关键字是会被分词的默认 query bool 查询多个字段的语法时候每个字段匹配到一个或多个的时候分数比一个字段匹配到查询分词的所有结果的分数来的大。但是对于我们来讲这样的不够精准的。所以我们希望查询字段中匹配的关键字越多排序越靠前而不是每个字段查询了一个分词就排前我们可以使用 dis_max。 但是使用 dis_max一般还不够建议再加上 tie_breaker。 tie_breaker 是一个小数值在 0~1 之间用来将其他查询结果分数乘以 tie_breaker 的值然后再综合与 dis_max 最高分数的的分数一起进行计算。除了取 dis_max 的最高分以外还会考虑其他的查询结果的分数。 在 dis_max 基础上为了增加精准我们还可以加上boost、minimum_should_match 等相关参数。其中 minimum_should_match 比较常用因为查询字段的分词中如果只有一个分词查询上了这种结果基本是没啥用的。 官网资料Best Fields | Elasticsearch: The Definitive Guide [2.x] | Elastic
GET /product_index/product/_search
{query: {dis_max: {queries: [{match: {product_name: PHILIPS toothbrush}},{match: {product_desc: iphone shell}}],tie_breaker: 0.2}}
}GET /product_index/product/_search
{query: {dis_max: {queries: [{match: {product_name: {query: PHILIPS toothbrush,minimum_should_match: 50%,boost: 3}}},{match: {product_desc: {query: iphone shell,minimum_should_match: 50%boost: 2}}}],tie_breaker: 0.3}}
} prefix 前缀搜索性能较差扫描所有倒排索引 比如有一个不分词字段 product_name分别有两个 doc 是iphone-6iphone-7。我们搜索 iphone 这个前缀关键字就可以搜索到结果
GET /product_index/product/_search
{query: {prefix: {product_name: {value: iphone}}}
} 通配符搜索性能较差扫描所有倒排索引
GET /product_index/product/_search
{query: {wildcard: {product_name: {value: ipho*}}}
} 正则搜索性能较差扫描所有倒排索引
GET /product_index/product/_search
{query: {regexp: {product_name: iphone[0-9].}}
} fuzzy 纠错查询 参数 fuzziness 默认是 2表示最多可以纠错两次但是这个值不能很大不然没效果。一般 AUTO 是自动纠错。 下面的关键字漏了一个字母 o。
GET /product_index/product/_search
{query: {match: {product_name: {query: PHILIPS tothbrush,fuzziness: AUTO,operator: and}}}
}