我們到現(xiàn)在只搜索過準(zhǔn)確的數(shù)字,現(xiàn)實(shí)中,通過范圍來過濾更為有用。例如,你可能希望找到所有價(jià)格高于 20 元而低于 40 元的產(chǎn)品。
在 SQL 語法中,范圍可以如下表示:
SELECT document
FROM products
WHERE price BETWEEN 20 AND 40
Elasticsearch 有一個 range
過濾器,讓你可以根據(jù)范圍過濾:
"range" : {
"price" : {
"gt" : 20,
"lt" : 40
}
}
range
過濾器既能包含也能排除范圍,通過下面的選項(xiàng):
gt
: >
大于lt
: <
小于gte
: >=
大于或等于lte
: <=
小于或等于下面是范圍過濾器的一個示例:
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"range" : {
"price" : {
"gte" : 20,
"lt" : 40
}
}
}
}
}
}
假如你需要不設(shè)限的范圍,去掉一邊的限制就可以了:
"range" : {
"price" : {
"gt" : 20
}
}
range
過濾器也可以用于日期字段:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-07 00:00:00"
}
}
當(dāng)用于日期字段時,range
過濾器支持_日期數(shù)學(xué)_操作。例如,我們想找到所有最近一個小時的文檔:
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
這個過濾器將始終能找出所有時間戳大于當(dāng)前時間減 1 小時的文檔,讓這個過濾器像_移窗_一樣通過你的文檔。
日期計(jì)算也能用于實(shí)際的日期,而不是僅僅是一個像 now 一樣的占位符。只要在日期后加上雙豎線 ||
,就能使用日期數(shù)學(xué)表達(dá)式了。
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-01 00:00:00||+1M" <1>
}
}
早于 2014 年 1 月 1 號加一個月 日期計(jì)算是與_日歷相關(guān)_的,所以它知道每個月的天數(shù),每年的天數(shù),等等。更詳細(xì)的關(guān)于日期的信息可以在這里找到 [日期格式手冊](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-date-format.html) #### 字符串范圍 `range` 過濾器也可以用于字符串。字符串范圍根據(jù)_字典_或字母順序來計(jì)算。例如,這些值按照字典順序排序: * 5, 50, 6, B, C, a, ab, abb, abc, b 提示:倒排索引中的短語按照字典順序排序,也是為什么字符串范圍使用這個順序。 假如我們想讓范圍從 `a` 開始而不包含 `b`,我們可以用類似的 `range` 過濾器語法: ```json "range" : { "title" : { "gte" : "a", "lt" : "b" } } ``` 當(dāng)心基數(shù): 數(shù)字和日期字段的索引方式讓他們在計(jì)算范圍時十分高效。但對于字符串來說卻不是這樣。為了在字符串上執(zhí)行范圍操作,Elasticsearch 會在這個范圍內(nèi)的每個短語執(zhí)行 `term` 操作。這比日期或數(shù)字的范圍操作慢得多。 字符串范圍適用于一個基數(shù)較小的字段,一個唯一短語個數(shù)較少的字段。你的唯一短語數(shù)越多,搜索就越慢。