https://www.iteblog.com/archives/1741.html
1. 基本匹配查询(Basic Match Query)
基本匹配查询主要有两种形式:
(1)使用Search Lite API,并将所有的搜索参数都通过URL传递;
GET /_all/tweet/_search?q=tweet:elasticsearch
查询type是tweet并且字段“tweet”包含"elasticsearch"的document
(2)使用Elasticsearch DSL,其可以通过传递一个JSON请求来获取结果。
GET /_search
{
"query": {
"match": {
"tweet":"elasticsearch"}
}
}
DSL方式提供了更加灵活的方式来构建更加复杂的查询,甚至指定你想要的返回结果。
例如:指定需要返回结果的数量,开始的偏移量(这在分页的情况下非常有用),需要返回document中的哪些字段以及高亮关键字:
{
"query": {
"match" : {
"title" : "in action" //查询title中包含in或action
}
},
"size": 2, //返回结果的数量
"from": 0, //开始的偏移量
"_source": [ "title", "summary", "publish_date" ], //指定返回document中的字段
"highlight": { //高亮title字段
"fields" : {
"title" : {}
}
}
}
2. 多字段查询
使用muliti_match查询:
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
//指定查询的多个字段,title或summary字段中包含elasticsearch或guide
"fields": ["title", "summary"]
}
}
}
3. Boosting查询
在查询中改变特定字段的相关度。
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
"fields": ["title", "summary^3"] //增大summary的相关度,权重调整为3
}
},
"_source": ["title", "summary", "publish_date"]
}
【注】Boosting不仅仅意味着计算出来的分数(calculated score)直接乘以boost factor,最终的boost value会经过归一化以及其他一些内部的优化。
4. bool查询
在查询条件中使用AND/OR/NOT操作符,这就是布尔查询(Bool Query)。Bool查询现在包括四种子句:must,filter,should,must_not。
{
"query": {
"bool": {
"must": {
"bool" : { "should": [
{ "match": { "title": "Elasticsearch" }},
{ "match": { "title": "Solr" }} ] }
},
"must": { "match": { "authors": "clinton gormely" }},
"must_not": { "match": {"authors": "radu gheorge" }}
}
}
}
查询title中出现Elasticsearch或者Solr关键字的图书,图书的作者是clinton gormley,但没有radu gheorge
【注】filter查询比query快:
query的时候,会先比较查询条件,然后计算分值,最后返回文档结果;
而filter则是先判断是否满足查询条件,如果不满足,会缓存查询过程(记录该文档不满足结果);满足的话,就直接缓存结果并返回。
综上所述,filter快在两个方面:
- 1 对结果进行缓存
- 2 避免计算分值
5. Fuzzy Queries(模糊查询)
模糊查询可以在Match
和 Multi-Match
查询中使用以便解决拼写的错误,模糊度是基于Levenshtein distance计算与原单词的距离。
{
"query": {
"multi_match" : {
"query" : "comprihensiv guide",
"fields": ["title", "summary"],
"fuzziness": "AUTO" //指定模糊查询
}
},
"_source": ["title", "summary", "publish_date"],
"size": 1
}
【注】将fuzziness的值指定为
AUTO
,其在term的长度大于5的时候相当于指定值为2。然而80%的人拼写错误的编辑距离(edit distance)为1,所有如果你将fuzziness设置为1可能会提高你的搜索性能。
6. Wildcard Query(通配符查询)
通配符查询允许我们指定一个模式来匹配,而不需要指定完整的trem。?
将会匹配任何字符;*
将会匹配零个或者多个字符。
{
"query": {
"wildcard" : {
"authors" : "t*" //author中包含以t开头
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
7. Regexp Query(正则表达式查询)
{
"query": {
"regexp" : {
"authors" : "t[a-z]*y" //以t开头,中间包含若干个a-z,以y结束,使用正则表达式
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
8. Match Phrase Query(匹配短语查询)
匹配短语查询要求查询字符串中的trems都出现Document中或者trems按照输入顺序依次出现在结果中。
可以指定**slop
**参数,来控制输入的trems之间有多少个单词(距离)仍然能够搜索到。
{
"query": {
"multi_match": {
"query": "search engine",
"fields": [
"title",
"summary"
],
"type": "phrase", //指定匹配词组
"slop": 3 //指定词组中单词之间的距离不大于3
}
},
"_source": [
"title",
"summary",
"publish_date"
]
}
9. Match Phrase Prefix Query(匹配短语前缀查询)
匹配短语前缀查询可以指定单词的一部分字符前缀即可查询到该单词,和match phrase query一样我们也可以指定slop
参数;同时其还支持 max_expansions 控制最后一个单词会被重写成多少个前缀,也就是,控制前缀扩展成分词的数量。
{
"query": {
"match_phrase_prefix": { //匹配前缀查询
"summary": {
"query": "search en",
"slop": 3, //距离为3
"max_expansions": 10 //前缀查询可被扩展到的词条数
}
}
},
"_source": [
"title",
"summary",
"publish_date"
]
}
【注】匹配短语前缀查询是有性能消耗的,所有使用之前需要小心。
10. Query String
query_string查询提供了一种手段可以使用一种简洁的方式运行multi_match queries, bool queries, boosting, fuzzy matching, wildcards, regexp以及range queries的组合查询。
{
"query": {
"query_string" : {
"query": "(search
1 algorithm1) AND (grant ingersoll) OR (tom morton)","fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
11. Simple Query String(简单查询字符串)
simple_query_string
是query_string
的另一种版本,其更适合为用户提供一个搜索框中,因为其使用+/|/- 分别替换AND/OR/NOT,如果用输入了错误的查询,其直接忽略这种情况而不是抛出异常。
{
"query": {
"simple_query_string" : { //简单查询字符串
"query": "(saerch
1 algorithm1) + (grant ingersoll) | (tom morton)","fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
12. Term/Terms Query 精确查询
{
"query": {
"term" : { //查询publisher = manning
"publisher": "manning"
}
},
"_source" : ["title","publish_date","publisher"]
}
{
"query": {
"terms" : { //查询多个匹配,或
"publisher": ["oreilly", "packt"]
}
}
}
13. Term Query - Sorted
词查询结果和其他查询结果一样可以很容易地对其进行排序,而且我们可以对输出结果按照多层进行排序。
{
"query": {
"term" : {
"publisher": "manning"
}
}, //查询publisher = manning的图书
"_source" : ["title","publish_date","publisher"],
"sort": [ //对查询到的结果排序,按照出版日期或title
{ "publish_date": {"order":"desc"}},
{ "title": { "order": "desc" }}
]
}
14. Range Query(范围查询)
{
"query": {
"range" : { //范围查询,按照出版日期
"publish_date": {
"gte": "2015-01-01",
"lte": "2015-12-31"
}
}
},
"_source" : ["title","publish_date","publisher"]
}
范围查询可以应用于日期,数字以及字符类型的字段。
15. Filtered Query(过滤查询)
过滤查询允许我们对查询结果进行筛选。
{
"query": {
"filtered": { //返回过滤之后的结果,5.0之后不再使用了
"query" : {
"multi_match": { //多字段匹配查询
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": { //对范围进行过滤
"range" : {
"num_reviews": {
"gte": 20
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews"]
}
【注】过滤查询(Filtered queries)并不强制过滤条件中指定查询。如果没有指定查询条件,则会运行
match_all
查询,其将会返回index中所有文档,然后对其进行过滤。在实际运用中,过滤器应该先被执行,这样可以减少需要查询的范围。而且,第一次使用fliter之后其将会被缓存,这样会对性能代理提升。
Filtered queries在Elasticsearch 5.0中移除了,我们可以使用
bool
查询来替换它。下面是使用bool查询来实现上面一样的查询效果,返回结果一样 。{
"query": {
"bool": {
"must" : {
"multi_match": {
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": {
"range" : {
"num_reviews": {
"gte": 20
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews"]
}
16. Multiple Filters(多过滤器查询)
{
"query": {
"filtered": {
"query" : {
"multi_match": {
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": {
"bool": {
"must": {
"range" : { "num_reviews": { "gte": 20 } }
},
"must_not": {
"range" : { "publish_date": { "lte": "2014-12-31" } }
},
"should": {
"term": { "publisher": "oreilly" }
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews", "publish_date"]
}
17. Function Score: Field Value Factor 处理分值计算过程
在某些场景下,你可能想对某个特定字段设置一个因子(factor),并通过这个因子计算某个文档的相关度(relevance score)。这是典型的基于文档(document)的重要性来抬高其相关性的方式。
{
"query": {
"function_score": { //
"query": {
"multi_match" : {
"query" : "search engine",
"fields": ["title", "summary"]
}
},
"field_value_factor": {
"field" : "num_reviews",
"modifier": "log1p",
"factor" : 2
}
}
},
"_source": ["title", "summary", "publish_date", "num_reviews"]
}
18. Function Score: Decay Functions
**Decay Functions主要有三种:分别是linear
、exp
以及gauss
**,分别用于操作数字字段(numeric fields)、日期字段(date fields)以及经/纬度的地理点。这三种Decay Functions都接收以下四种参数:
1、origin
:中心点,或者是该字段最有可能的值。所有落在中心点的文档的得分(_score
)都是1.0;
2、scale
:衰减率。指的是一个文档距离origin
获得_score
的需要减少多少;
3、decay
:衰减。指的是一个文档在相对于origin的scale距离应该得到的_score
,默认值是0.5;
4、offset
:偏移,所有落入-offset < = origin <= +offset
范围的值都将得到1.0的_score
。
下图展示了这三种Decay Functions的区别:
gauss 衰减速度先慢后快再慢,exp 衰减速度先快后慢,lin 直线衰减,在0分外的值都是0分,如何选择取决于你想要你的score以什么速度衰减。
{
"query": {
"function_score": {
"query": {
"multi_match" : {
"query" : "search engine",
"fields": ["title", "summary"]
}
},
"functions": [
{
"exp": {
"publish_date" : {
"origin": "2014-06-15",
"offset": "7d",
"scale" : "30d"
}
}
}
],
"boost_mode" : "replace"
}
},
"_source": ["title", "summary", "publish_date", "num_reviews"]
}
19. Function Score: Script Scoring
如果内置的scoring functions满足不了你的需求,我们就可以使用Script Scoring,通过指定一个Groovy script来计算分数。
计算分数的脚本如下:
publish_date = doc[``'publish_date'``].value
num_reviews = doc[``'num_reviews'``].value
if
(publish_date > Date.parse(``'yyyy-MM-dd'``, threshold).getTime()) {
my_score = Math.log(``2.5
+ num_reviews)
}
else
{
my_score = Math.log(``1
+ num_reviews)
}
return
my_score
{
"query"``: {
"function_score"``: {
"query"``: {
"multi_match"
: {
"query"
:
"search engine"``,
"fields"``: [``"title"``,
"summary"``]
}
},
"functions"``: [
{
"script_score"``: {
"params"
: {
"threshold"``:
"2015-07-30"
},
"script"``:
"publish_date = doc['publish_date'].value; num_reviews = doc['num_reviews'].value; if (publish_date > Date.parse('yyyy-MM-dd', threshold).getTime()) { return log(2.5 + num_reviews) }; return log(1 + num_reviews);"
}
}
]
}
},
"_source"``: [``"title"``,
"summary"``,
"publish_date"``,
"num_reviews"``]
}