對于準(zhǔn)確值,你需要使用過濾器。過濾器的重要性在于它們非常的快。它們不計(jì)算相關(guān)性(避過所有計(jì)分階段)而且很容易被緩存。我們今后再來討論過濾器的性能優(yōu)勢【過濾器緩存】,現(xiàn)在,請先記住盡可能多的使用過濾器。
term
過濾器我們下面將介紹 term
過濾器,首先因?yàn)槟憧赡芙?jīng)常會(huì)用到它,這個(gè)過濾器旨在處理數(shù)字,布爾值,日期,和文本。
我們來看一下例子,一些產(chǎn)品最初用數(shù)字來索引,包含兩個(gè)字段 price
和 productID
:
POST /my_store/products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }
我們的目標(biāo)是找出特定價(jià)格的產(chǎn)品。假如你有關(guān)系型數(shù)據(jù)庫背景,可能用 SQL 來表現(xiàn)這次查詢比較熟悉,它看起來像這樣:
SELECT document
FROM products
WHERE price = 20
在 Elasticsearch DSL 中,我們使用 term
過濾器來實(shí)現(xiàn)同樣的事。term
過濾器會(huì)查找我們設(shè)定的準(zhǔn)確值。term
過濾器本身很簡單,它接受一個(gè)字段名和我們希望查找的值:
{
"term" : {
"price" : 20
}
}
term
過濾器本身并不能起作用。像在【查詢 DSL】中介紹的一樣,搜索 API 需要得到一個(gè)查詢語句
,而不是一個(gè) 過濾器
。為了使用 term
過濾器,我們需要將它包含在一個(gè)過濾查詢語句中:
GET /my_store/products/_search
{
"query" : {
"filtered" : { <1>
"query" : {
"match_all" : {} <2>
},
"filter" : {
"term" : { <3>
"price" : 20
}
}
}
}
}
`filtered` 查詢同時(shí)接受 `query` 與 `filter`。
`match_all` 用來匹配所有文檔,這是默認(rèn)行為,所以在以后的例子中我們將省略掉 `query` 部分。
這是我們上面見過的 `term` 過濾器。注意它在 `filter` 分句中的位置。
執(zhí)行之后,你將得到預(yù)期的搜索結(jié)果:只能文檔 2 被返回了(因?yàn)橹挥?`2` 的價(jià)格是 `20`):
```json
"hits" : [
{
"_index" : "my_store",
"_type" : "products",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"price" : 20,
"productID" : "KDKE-B-9947-#kL5"
}
}
]
```
過濾器不會(huì)執(zhí)行計(jì)分和計(jì)算相關(guān)性。分值由 `match_all` 查詢產(chǎn)生,所有文檔一視同仁,所有每個(gè)結(jié)果的分值都是 `1`
#### 用于文本的 `term` 過濾器
像我們在開頭提到的,`term` 過濾器可以像匹配數(shù)字一樣輕松的匹配字符串。讓我們通過特定 UPC 標(biāo)識(shí)碼來找出產(chǎn)品,而不是通過價(jià)格。如果用 SQL 來實(shí)現(xiàn),我們可能會(huì)使用下面的查詢:
```sql
SELECT product
FROM products
WHERE productID = "XHDK-A-1293-#fJ3"
```
轉(zhuǎn)到查詢 DSL,我們用 `term` 過濾器來構(gòu)造一個(gè)類似的查詢:
```json
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
```
有點(diǎn)出乎意料:我們沒有得到任何結(jié)果值!為什么呢?問題不在于 `term` 查詢;而在于數(shù)據(jù)被索引的方式。如果我們使用 `analyze` API,我們可以看到 UPC 被分解成短小的表征:
```json
GET /my_store/_analyze?field=productID
XHDK-A-1293-#fJ3
```
```json
{
"tokens" : [ {
"token" : "xhdk",
"start_offset" : 0,
"end_offset" : 4,
"type" : "