轉載自:https://www.cnblogs.com/sunfie/p/6653778.html
安裝啟動很簡單,參考官網步驟:https://www.elastic.co/downloads/elasticsearch
為了介紹Elasticsearch中的不同查詢類型,我們將對帶有下列字段的文檔進行搜索:title(標題),authors(作者),summary(摘要),release date(發布時間)以及number of reviews(評論數量),首先,讓我們創建一個新的索引,並通過bulk API查詢文檔:
為了展示Elasticsearch中不同查詢的用法,首先在Elasticsearch里面創建了employee相關的documents,每本書主要涉及以下字段: first_name, last_name, age,about,interests,操作如下:
1 curl -XPUT 'localhost:9200/megacorp/employee/3' -d '{ "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about" : "I like to build cabinets", "interests": "forestry" }'
2 curl -XPUT 'localhost:9200/megacorp/employee/2' -d '{ "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests": "music" }'
3 curl -XPUT 'localhost:9200/megacorp/employee/1' -d '{ "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] }'
1. 基本匹配查詢(Basic Match Query)
基本匹配查詢主要有兩種形式:(1)使用Search Lite API,並將所有的搜索參數都通過URL傳遞;
(2)使用Elasticsearch DSL,其可以通過傳遞一個JSON請求來獲取結果。下面是在所有的字段中搜索帶有"John"的結果
1 curl -XGET 'localhost:9200/megacorp/employee/_search?q=John'
如果我們使用Query DSL來展示出上面一樣的結果可以這么來寫:
curl -XGET 'localhost:9200/megacorp/_search' -d '
{
"query": {
"multi_match" : {
"query" : "John",
"fields" : ["_all"]
}
}
}'
其輸出和上面使用/_search?q=john的輸出一樣。上面的multi_match關鍵字通常在查詢多個fields的時候作為match關鍵字的簡寫方式。fields屬性指定需要查詢的字段,如果我們想查詢所有的字段,這時候可以使用_all關鍵字,正如上面的一樣。以上兩種方式都允許我們指定查詢哪些字段。比如,我們想查詢interest中出現music的員工,那么我們可以這么查詢:
1 curl -XGET 'localhost:9200/megacorp/employee/_search?q=interests:music'
然而,DSL方式提供了更加靈活的方式來構建更加復雜的查詢(我們將在后面看到),甚至指定你想要的返回結果。下面的例子中,我將指定需要返回結果的數量,開始的偏移量(這在分頁的情況下非常有用),需要返回document中的哪些字段以及高亮關鍵字:
curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -d '{"query": { "match" : { "interests" : "music" }},"size": 2,"from": 0,"_source": [ "first_name", "last_name", "interests" ],"highlight": {"fields" : { "interests" : { } } } }'
需要注意的是:對於查詢多個關鍵字,match關鍵字允許我們使用and操作符來代替默認的or操作符。你也可以指定minimum_should_match操作符來調整返回結果的相關性(tweakrelevance)。
2. Multi-field Search
正如我們之前所看到的,想在一個搜索中查詢多個 document field (比如使用同一個查詢關鍵字同時在title和summary中查詢),你可以使用multi_match查詢,使用如下:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"multi_match" : {
"query" : "rock",
"fields": ["about", "interests"]
}
}
}'
3. Boosting
我們上面使用同一個搜索請求在多個field中查詢,你也許想提高某個field的查詢權重,在下面的例子中,我們把interests的權重調成3,這樣就提高了其在結果中的權重,這樣把_id=4的文檔相關性大大提高了,如下:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"multi_match" : {
"query" : "rock",
"fields": ["about", "interests^3"]
}
}
}'
Boosting不僅僅意味着計算出來的分數(calculated score)直接乘以boost factor,最終的boost value會經過歸一化以及其他一些內部的優化
4. Bool Query
我們可以在查詢條件中使用AND/OR/NOT操作符,這就是布爾查詢(Bool Query)。布爾查詢可以接受一個must參數(等價於AND),一個must_not參數(等價於NOT),以及一個should參數(等價於OR)。比如,我想查詢about中出現music或者climb關鍵字的員工,員工的名字是John,但姓氏不是smith,我們可以這么來查詢:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"bool": {
"must": {
"bool" : {
"should": [
{ "match": { "about": "music" }},
{ "match": { "about": "climb" }} ]
}
},
"must": {
"match": { "first_nale": "John" }
},
"must_not": {
"match": {"last_name": "Smith" }
}
}
}
}'
5. Fuzzy Queries(模糊查詢)
模糊查詢可以在Match和 Multi-Match查詢中使用以便解決拼寫的錯誤,模糊度是基於Levenshteindistance計算與原單詞的距離。使用如下:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"multi_match" : {
"query" : "rock climb",
"fields": ["about", "interests"],
"fuzziness": "AUTO"
}
},
"_source": ["about", "interests", "first_name"],
"size": 1
}'
上面我們將fuzziness的值指定為AUTO,其在term的長度大於5的時候相當於指定值為2,然而80%的人拼寫錯誤的編輯距離(edit distance)為1,所有如果你將fuzziness設置為1可能會提高你的搜索性能
6. Wildcard Query(通配符查詢)
通配符查詢允許我們指定一個模式來匹配,而不需要指定完整的trem。?將會匹配如何字符;*將會匹配零個或者多個字符。比如我們想查找所有名字中以J字符開始的記錄,我們可以如下使用:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"wildcard" : {
"first_name" : "s*"
}
},
"_source": ["first_name", "last_name"],
"highlight": {
"fields" : {
"first_name" : {}
}
}
}'
7. Regexp Query(正則表達式查詢)
ElasticSearch還支持正則表達式查詢,此方式提供了比通配符查詢更加復雜的模式。比如我們先查找作者名字以J字符開頭,中間是若干個a-z之間的字符,並且以字符n結束的記錄,可以如下查詢:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"regexp" : {
"first_name" : "J[a-z]*n"
}
},
"_source": ["first_name", "age"],
"highlight": {
"fields" : {
"first_name" : {}
}
}
}'
8. Match Phrase Query(匹配短語查詢)
匹配短語查詢要求查詢字符串中的trems要么都出現Document中、要么trems按照輸入順序依次出現在結果中。在默認情況下,查詢輸入的trems必須在搜索字符串緊挨着出現,否則將查詢不到。不過我們可以指定slop參數,來控制輸入的trems之間有多少個單詞仍然能夠搜索到,如下所示:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"multi_match": {
"query": "climb rock",
"fields": [
"about",
"interests"
],
"type": "phrase",
"slop": 3
}
},
"_source": [
"title",
"about",
"interests"
]
}'
從上面的例子可以看出,id為4的document被搜索(about字段里面精確匹配到了climb rock),並且分數比較高;而id為1的document也被搜索到了,雖然其about中的climb和rock單詞並不是緊挨着的,但是我們指定了slop屬性,所以被搜索到了。如果我們將"slop":3條件刪除,那么id為1的文檔將不會被搜索到。
9. Match Phrase Prefix Query(匹配短語前綴查詢)
匹配短語前綴查詢可以指定單詞的一部分字符前綴即可查詢到該單詞,和match phrase query一樣我們也可以指定slop參數;同時其還支持max_expansions參數限制被匹配到的terms數量來減少資源的使用,使用如下:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"match_phrase_prefix": {
"summary": {
"query": "cli ro",
"slop": 3,
"max_expansions": 10
}
}
},
"_source": [
"about",
"interests",
"first_name"
]
}'
10. Query String
query_string查詢提供了一種手段可以使用一種簡潔的方式運行multi_match queries, bool queries, boosting, fuzzy matching, wildcards, regexp以及range queries的組合查詢。在下面的例子中,我們運行了一個模糊搜索(fuzzy search),搜索關鍵字是search algorithm,並且作者包含grant ingersoll或者tom morton。並且搜索了所有的字段,其中summary字段的權重為2:
curl -XGET 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"query_string" : {
"query": "(saerch~1 algorithm~1) 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,如果用輸入了錯誤的查詢,其直接忽略這種情況而不是拋出異常。使用如下:
curl -POST 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"simple_query_string" : {
"query": "(saerch~1 algorithm~1) + (grant ingersoll) | (tom morton)",
"fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}'
12. Term/Terms Query
前面的例子中我們已經介紹了全文搜索(full-text search),但有時候我們對結構化搜索中能夠精確匹配並返回搜索結果更感興趣。這種情況下我們可以使用term和terms查詢。在下面例子中,我們想搜索所有興趣中有music的人:
curl -POST 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"term" : {
"interests": "music"
}
},
"_source" : ["first_name","last_name","interests"]
}'
我們還可以使用terms關鍵字來指定多個terms,如下:
{
"query": {
"terms" : {
"publisher": ["oreilly", "packt"]
}
}
}
13. Term Query - Sorted
查詢結果和其他查詢結果一樣可以很容易地對其進行排序,而且我們可以對輸出結果按照多層進行排序:
curl -XPOST 'localhost:9200/megacorp/employee/_search' -d '
{
"query": {
"term" : {
"interests": "music"
}
},
"_source" : ["interests","first_name","about"],
"sort": [
{ "publish_date": {"order":"desc"}},
{ "id": { "order": "desc" }}
]
}'
14. Range Query(范圍查詢)
另一種結構化查詢就是范圍查詢。在下面例子中,我們搜索所有發行年份為2015的圖書:
curl -XPOST 'localhost:9200/person/worker/_search?pretty' -d '
{
"query": {
"range" : {
"birthday": {
"gte": "2017-02-01",
"lte": "2017-05-01"
}
}
},
"_source" : ["first_name","last_name","birthday"]
}'
范圍查詢可以應用於日期,數字以及字符類型的字段。
15. Filtered Query(過濾查詢)
過濾查詢允許我們對查詢結果進行篩選。比如:我們查詢about和interests中包含music關鍵字的員工,但是我們想過濾出birthday大於2017/02/01的結果,可以如下使用:
curl -XPOST :9200/megacorp/employee/_search?pretty' -d '
{
"query": {
"filtered": {
"query" : {
"multi_match": {
"query": "music",
"fields": ["about","interests"]
}
},
"filter": {
"range" : {
"birthday": {
"gte": 2017-02-01
}
}
}
}
},
"_source" : ["first_name","last_name","about", "interests"]
}'
注意:過濾查詢(Filtered queries)並不強制過濾條件中指定查詢,如果沒有指定查詢條件,則會運行match_all查詢,其將會返回index中所有文檔,然后對其進行過濾,在實際運用中,過濾器應該先被執行,這樣可以減少需要查詢的范圍,而且,第一次使用fliter之后其將會被緩存,這樣會對性能代理提升。Filtered queries在即將發行的Elasticsearch 5.0中移除了,我們可以使用bool查詢來替換他,下面是使用bool查詢來實現上面一樣的查詢效果,返回結果一樣:
curl -XPOST 'localhost:9200/megacorp/employee/_search?pretty' -d '
{
"query": {
"bool": {
"must" : {
"multi_match": {
"query": "music",
"fields": ["about","interests"]
}
},
"filter": {
"range" : {
"birthday": {
"gte": 2017-02-01
}
}
}
}
},
"_source" : ["first_name","last_name","about", "interests"]
}'
16. Multiple Filters(多過濾器查詢)
多過濾器查詢可以通過結合使用bool過濾查詢實現。下面的示例中,我們將篩選出返回的結果必須至少有20條評論,必須是在2015年之前發布的,而且應該是由O'Reilly出版的,首先建立索引iteblog_book_index並向其插入數據,如下所示:
curl -XPOST 'localhost:9200/iteblog_book_index/book/1' -d '{ "title": "Elasticsearch: The Definitive Guide", "authors": ["clinton gormley", "zachary tong"], "summary" : "A distibuted real-time search and analytics engine", "publish_date" : "2015-02-07","num_reviews": 20, "publisher": "oreilly" }'
curl -XPOST 'localhost:9200/iteblog_book_index/book/2' -d '{ "title": "Taming Text: How to Find, Organize, and Manipulate It", "authors": ["grant ingersoll", "thomas morton", "drew farris"], "summary" : "organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization", "publish_date" : "2013-01-24", "num_reviews": 12, "publisher": "manning" }'
curl -XPOST 'localhost:9200/iteblog_book_index/book/3' -d '{ "title": "Elasticsearch in Action", "authors": ["radu gheorge", "matthew lee hinman", "roy russo"], "summary" : "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms", "publish_date" : "2015-12-03", "num_reviews": 18, "publisher": "manning" }'
curl -XPOST 'localhost:9200/iteblog_book_index/book/4' -d '{ "title": "Solr in Action", "authors": ["trey grainger", "timothy potter"], "summary" : "Comprehensive guide to implementing a scalable search engine using Apache Solr", "publish_date" : "2014-04-05", "num_reviews": 23, "publisher": "manning" }'
然后執行如下查詢語句:
curl -XPOST 'localhost:9200/iteblog_book_index/book/_search?pretty' -d '
{
"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)的重要性來抬高其相關性的方式。在下面例子中,我們想找到更受歡迎的圖書(是通過圖書的評論實現的),並將其權重抬高,這里可以通過使用field_value_factor來實現
curl -XPOST 'localhost:9200/iteblog_book_index/book/_search?pretty' -d '
{
"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"]
}'

