https://www.iteblog.com/archives/1741.htmlhtml
基本匹配查询主要有两种形式:正则表达式
(1)使用Search Lite API,并将全部的搜索参数都经过URL传递;缓存
GET /_all/tweet/_search?q=tweet:elasticsearchelasticsearch
查询type是tweet而且字段“tweet”包含"elasticsearch"的documentide
(2)使用Elasticsearch DSL,其能够经过传递一个JSON请求来获取结果。性能
GET /_search
{
"query": {
"match": {
"tweet":"elasticsearch"优化}
}
}ui
DSL方式提供了更加灵活的方式来构建更加复杂的查询,甚至指定你想要的返回结果。spa
例如:指定须要返回结果的数量,开始的偏移量(这在分页的状况下很是有用),须要返回document中的哪些字段以及高亮关键字:代理
{
"query": {
"match" : {
"title" : "in action" //查询title中包含in或action
}
},
"size": 2, //返回结果的数量
"from": 0, //开始的偏移量
"_source": [ "title", "summary", "publish_date" ], //指定返回document中的字段
"highlight": { //高亮title字段
"fields" : {
"title" : {}
}
}
}
使用muliti_match查询:
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
//指定查询的多个字段,title或summary字段中包含elasticsearch或guide
"fields": ["title", "summary"]
}
}
}
在查询中改变特定字段的相关度。
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
"fields": ["title", "summary^3"] //增大summary的相关度,权重调整为3
}
},
"_source": ["title", "summary", "publish_date"]
}
【注】Boosting不只仅意味着计算出来的分数(calculated score)直接乘以boost factor,最终的boost value会通过归一化以及其余一些内部的优化。
在查询条件中使用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 避免计算分值
模糊查询能够在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可能会提升你的搜索性能。
通配符查询容许咱们指定一个模式来匹配,而不须要指定完整的trem。?
将会匹配任何字符;*
将会匹配零个或者多个字符。
{
"query": {
"wildcard" : {
"authors" : "t*" //author中包含以t开头
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
{
"query": {
"regexp" : {
"authors" : "t[a-z]*y" //以t开头,中间包含若干个a-z,以y结束,使用正则表达式
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
匹配短语查询要求查询字符串中的trems都出现Document中或者trems按照输入顺序依次出如今结果中。
能够指定slop
参数,来控制输入的trems之间有多少个单词(距离)仍然可以搜索到。
{
"query": {
"multi_match": {
"query": "search engine",
"fields": [
"title",
"summary"
],
"type": "phrase", //指定匹配词组
"slop": 3 //指定词组中单词之间的距离不大于3
}
},
"_source": [
"title",
"summary",
"publish_date"
]
}
匹配短语前缀查询能够指定单词的一部分字符前缀便可查询到该单词,和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"
]
}
【注】匹配短语前缀查询是有性能消耗的,全部使用以前须要当心。
query_string查询提供了一种手段可使用一种简洁的方式运行multi_match queries, bool queries, boosting, fuzzy matching, wildcards, regexp以及range queries的组合查询。
{
"query": {
"query_string" : {
"query": "(search~1 algorithm~1) AND (grant ingersoll) OR (tom morton)",
"fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
simple_query_string
是query_string
的另外一种版本,其更适合为用户提供一个搜索框中,由于其使用+/|/- 分别替换AND/OR/NOT,若是用输入了错误的查询,其直接忽略这种状况而不是抛出异常。
{
"query": {
"simple_query_string" : { //简单查询字符串
"query": "(saerch~1 algorithm~1) + (grant ingersoll) | (tom morton)",
"fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
{
"query": {
"term" : { //查询publisher = manning
"publisher": "manning"
}
},
"_source" : ["title","publish_date","publisher"]
}
{
"query": {
"terms" : { //查询多个匹配,或
"publisher": ["oreilly", "packt"]
}
}
}
词查询结果和其余查询结果同样能够很容易地对其进行排序,并且咱们能够对输出结果按照多层进行排序。
{
"query": {
"term" : {
"publisher": "manning"
}
}, //查询publisher = manning的图书
"_source" : ["title","publish_date","publisher"],
"sort": [ //对查询到的结果排序,按照出版日期或title
{ "publish_date": {"order":"desc"}},
{ "title": { "order": "desc" }}
]
}
{
"query": {
"range" : { //范围查询,按照出版日期
"publish_date": {
"gte": "2015-01-01",
"lte": "2015-12-31"
}
}
},
"_source" : ["title","publish_date","publisher"]
}
范围查询能够应用于日期,数字以及字符类型的字段。
过滤查询容许咱们对查询结果进行筛选。
{
"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"]
}
{
"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"]
}
在某些场景下,你可能想对某个特定字段设置一个因子(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"]
}
Decay Functions主要有三种:分别是linear
、exp
以及gauss
,分别用于操做数字字段(numeric fields)、日期字段(date fields)以及经/纬度的地理点。这三种Decay Functions都接收如下四种参数:
一、origin
:中心点,或者是该字段最有可能的值。全部落在中心点的文档的得分(_score
)都是1.0;
二、scale
:衰减率。指的是一个文档距离origin
得到_score
的须要减小多少;
三、decay
:衰减。指的是一个文档在相对于origin的scale距离应该获得的_score
,默认值是0.5;
四、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"]
}
若是内置的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"
]
}