結構化搜索:在結構化查詢中,我們得到的結果總是非是即否,要么存在于集合之中,要么存在于集合之外,結構化查詢不關心文件的相關度或評分。
精確值查找:
當進行精確值查詢時,使用filters(過濾器),因為它的執行速度會很快,不會計算相關度,并且容易被緩存。請盡量使用過濾式查詢。
term差許小年,可以用來處理數字、布爾值、日期以及文本。
例如:查詢價格為20的所有產品
{
"term" : {
"price" : 20
}
}
通常進行一個精確值查詢的時候,通常不希望對查詢進行評分,所有會使用constant_score查詢以非評分的模式進行。
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"price" : 20
}
}
}
}
}
term文本查詢:
文本字段索引的方式應該是not_analyzed無分析的。
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
組合過濾器:
當使用多個字段進行過濾的時候,可以使用bool(布爾)過濾器,這是一個復合過濾器,可以接受多個其他過濾器作為參數,
并將這些過濾器組合成各種各樣的布爾邏輯。
使用SQL是:
SELECT product
FROM products
WHERE (price = 20 OR productID = "XHDK-A-1293-#fJ3")
AND (price != 30)
布爾過濾器:一個bool過濾器由三部分組成,
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}
must:必須匹配,與and等價
must_not:不能匹配,與not等價
should:至少一個語句要匹配,與or等價
這三個部分每個部分都是可選的,也就是說,例如我們可以在一個bool過濾器中只使用一個must語句。
將上面的SQL轉成es查詢:
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"should" : [
{ "term" : {"price" : 20}},
{ "term" : {"productID" : "XHDK-A-1293-#fJ3"}}
],
"must_not" : {
"term" : {"price" : 30}
}
}
}
}
}
}
嵌套布爾過濾器
bool過濾器可以接受多個子過濾器,可以將一個bool過濾器置于其他過濾器內部,這樣就可以對任意復雜的布爾邏輯進行處理。
下面的SQL語句:
SELECT document
FROM products
WHERE productID = "KDKE-B-9947-#kL5"
OR ( productID = "JODL-X-1937-#pV7"
AND price = 30 )
將其轉換成es查詢:
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"should" : [
{ "term" : {"productID" : "KDKE-B-9947-#kL5"}},
{ "bool" : {
"must" : [
{ "term" : {"productID" : "JODL-X-1937-#pV7"}},
{ "term" : {"price" : 30}}
]
}}
]
}
}
}
}
}
查找多個精確值
term差許小年對于查詢單個值非常有用,當時當我們搜索多個值時,可以使用terms查詢。
例如:我們要查找價格字段為20或30的文檔。
{
"terms" : {
"price" : [20, 30]
}
}
將其置入filter中:
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"terms" : {
"price" : [20, 30]
}
}
}
}
}
term和terms都是包含操作,而不是equals。
例如
如果我們有一個 term(詞項)過濾器 { "term" : { "tags" : "search" } } ,它會與以下兩個文檔 同時 匹配:
{ "tags" : ["search"] }
{ "tags" : ["search", "open_source"] }
如果要精確相等:
最好的方式是增加并索引另一個字段,這個字段用于存儲該字段包含詞項的數量,
GET /my_index/my_type/_search
{
"query": {
"constant_score" : {
"filter" : {
"bool" : {
"must" : [
{ "term" : { "tags" : "search" } },
{ "term" : { "tag_count" : 1 } }
]
}
}
}
}
}
現在這個查詢只會匹配具有單個標簽search的文檔。
范圍:
對數字范圍進行過濾,
例如我們想要查詢所有價格大于20且小于30的產品
SQL查詢語句為
select document
from products
where price between 20 and 40
使用es查詢為
"range" : {
"price" : {
"gte" : 20,
"lte" : 40
}
}
range 查詢可同時提供包含(inclusive)和不包含(exclusive)這兩種范圍表達式,可供組合的選項如下:
gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"price" : {
"gte" : 20,
"lt" : 40
}
}
}
}
}
}
日期范圍:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-07 00:00:00"
}
}
range查詢支持對日期計算進行操作,例如找到時間戳在過去一小時內的所有文檔。
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
日期計算可以被應用于某個具體的時間,只要在某個日期后面加上一個雙管符號(||)并緊跟一個日期數學表達式就可以:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-01 00:00:00||+1M" //加一個月( 2014 年 2 月 1 日 零時)
}
}
字符串范圍:
range還可以處理字符串字段。字符串范圍采用的是字典順序或者是字母順序。
如果查a到b(不包含)的字符串,可以使用:
"range" : {
"title" : {
"gte" : "a",
"lt" : "b"
}
}
日期或數字的索引方式可以高效的計算范圍,但是字符串不可以。
處理Null值
如果一個字段沒有值,那么它不會存入倒排索引中,這就意味著null,,[null]所有這些都是等價的,不會存在倒排索引中。