### 查找準確值
對于準確值,你需要使用過濾器。過濾器的重要性在于它們非常的快。它們不計算相關性(避過所有計分階段)而且很容易被緩存。我們今后再來討論過濾器的性能優勢【過濾器緩存】,現在,請先記住盡可能多的使用過濾器。
#### 用于數字的 `term` 過濾器
我們下面將介紹 `term` 過濾器,首先因為你可能經常會用到它,這個過濾器旨在處理數字,布爾值,日期,和文本。
我們來看一下例子,一些產品最初用數字來索引,包含兩個字段 `price` 和 `productID`:
```json
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" }
```
<!-- SENSE: 080_Structured_Search/05_Term_number.json -->
我們的目標是找出特定價格的產品。假如你有關系型數據庫背景,可能用 SQL 來表現這次查詢比較熟悉,它看起來像這樣:
```sql
SELECT document
FROM products
WHERE price = 20
```
在 Elasticsearch DSL 中,我們使用 `term` 過濾器來實現同樣的事。`term` 過濾器會查找我們設定的準確值。`term` 過濾器本身很簡單,它接受一個字段名和我們希望查找的值:
```json
{
"term" : {
"price" : 20
}
}
```
`term` 過濾器本身并不能起作用。像在【查詢 DSL】中介紹的一樣,搜索 API 需要得到一個`查詢語句`,而不是一個 `過濾器`。為了使用 `term` 過濾器,我們需要將它包含在一個過濾查詢語句中:
```json
GET /my_store/products/_search
{
"query" : {
"filtered" : { <1>
"query" : {
"match_all" : {} <2>
},
"filter" : {
"term" : { <3>
"price" : 20
}
}
}
}
}
```
<!-- SENSE: 080_Structured_Search/05_Term_number.json -->
<1> `filtered` 查詢同時接受 `query` 與 `filter`。
<2> `match_all` 用來匹配所有文檔,這是默認行為,所以在以后的例子中我們將省略掉 `query` 部分。
<3> 這是我們上面見過的 `term` 過濾器。注意它在 `filter` 分句中的位置。
執行之后,你將得到預期的搜索結果:只能文檔 2 被返回了(因為只有 `2` 的價格是 `20`):
```json
"hits" : [
{
"_index" : "my_store",
"_type" : "products",
"_id" : "2",
"_score" : 1.0, <1>
"_source" : {
"price" : 20,
"productID" : "KDKE-B-9947-#kL5"
}
}
]
```
<1> 過濾器不會執行計分和計算相關性。分值由 `match_all` 查詢產生,所有文檔一視同仁,所有每個結果的分值都是 `1`
#### 用于文本的 `term` 過濾器
像我們在開頭提到的,`term` 過濾器可以像匹配數字一樣輕松的匹配字符串。讓我們通過特定 UPC 標識碼來找出產品,而不是通過價格。如果用 SQL 來實現,我們可能會使用下面的查詢:
```sql
SELECT product
FROM products
WHERE productID = "XHDK-A-1293-#fJ3"
```
轉到查詢 DSL,我們用 `term` 過濾器來構造一個類似的查詢:
```json
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
```
<!-- SENSE: 080_Structured_Search/05_Term_text.json -->
有點出乎意料:我們沒有得到任何結果值!為什么呢?問題不在于 `term` 查詢;而在于數據被索引的方式。如果我們使用 `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" : "<ALPHANUM>",
"position" : 1
}, {
"token" : "a",
"start_offset" : 5,
"end_offset" : 6,
"type" : "<ALPHANUM>",
"position" : 2
}, {
"token" : "1293",
"start_offset" : 7,
"end_offset" : 11,
"type" : "<NUM>",
"position" : 3
}, {
"token" : "fj3",
"start_offset" : 13,
"end_offset" : 16,
"type" : "<ALPHANUM>",
"position" : 4
} ]
}
```
<!-- SENSE: 080_Structured_Search/05_Term_text.json -->
這里有一些要點:
* 我們得到了四個分開的標記,而不是一個完整的標記來表示 UPC。
* 所有的字符都被轉為了小寫。
* 我們失去了連字符和 `#` 符號。
所以當我們用 `XHDK-A-1293-#fJ3` 來查找時,得不到任何結果,因為這個標記不在我們的倒排索引中。相反,那里有上面列出的四個標記。
顯然,在處理唯一標識碼,或其他枚舉值時,這不是我們想要的結果。
為了避免這種情況發生,我們需要通過設置這個字段為 `not_analyzed` 來告訴 Elasticsearch 它包含一個準確值。我們曾在【自定義字段映射】中見過它。為了實現目標,我們要先刪除舊索引(因為它包含了錯誤的映射),并創建一個正確映射的索引:
```json
DELETE /my_store <1>
PUT /my_store <2>
{
"mappings" : {
"products" : {
"properties" : {
"productID" : {
"type" : "string",
"index" : "not_analyzed" <3>
}
}
}
}
}
```
<!-- SENSE: 080_Structured_Search/05_Term_text.json -->
<1> 必須首先刪除索引,因為我們不能修改已經存在的映射。
<2> 刪除后,我們可以用自定義的映射來創建它。
<3> 這里我們明確表示不希望 `productID` 被分析。
現在我們可以繼續重新索引文檔:
```json
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" }
```
<!-- SENSE: 080_Structured_Search/05_Term_text.json -->
現在我們的 `term` 過濾器將按預期工作。讓我們在新索引的數據上再試一次(注意,查詢和過濾都沒有修改,只是數據被重新映射了)。
```json
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
```
<!-- SENSE: 080_Structured_Search/05_Term_text.json -->
`productID` 字段沒有經過分析,`term` 過濾器也沒有執行分析,所以這條查詢找到了準確匹配的值,如期返回了文檔 1。
#### 內部過濾操作
Elasticsearch 在內部會通過一些操作來執行一次過濾:
1. _查找匹配文檔_。
`term` 過濾器在倒排索引中查找詞 `XHDK-A-1293-#fJ3`,然后返回包含那個詞的文檔列表。在這個例子中,只有文檔 1 有我們想要的詞。
2. _創建字節集_
然后過濾器將創建一個 _字節集_ —— 一個由 1 和 0 組成的數組 —— 描述哪些文檔包含這個詞。匹配的文檔得到 `1` 字節,在我們的例子中,字節集將是 `[1,0,0,0]`
3. _緩存字節集_
最后,字節集被儲存在內存中,以使我們能用它來跳過步驟 1 和 2。這大大的提升了性能,讓過濾變得非常的快。
當執行 `filtered` 查詢時,`filter` 會比 `query` 早執行。結果字節集會被傳給 `query` 來跳過已經被排除的文檔。這種過濾器提升性能的方式,查詢更少的文檔意味著更快的速度。
- Introduction
- 入門
- 是什么
- 安裝
- API
- 文檔
- 索引
- 搜索
- 聚合
- 小結
- 分布式
- 結語
- 分布式集群
- 空集群
- 集群健康
- 添加索引
- 故障轉移
- 橫向擴展
- 更多擴展
- 應對故障
- 數據
- 文檔
- 索引
- 獲取
- 存在
- 更新
- 創建
- 刪除
- 版本控制
- 局部更新
- Mget
- 批量
- 結語
- 分布式增刪改查
- 路由
- 分片交互
- 新建、索引和刪除
- 檢索
- 局部更新
- 批量請求
- 批量格式
- 搜索
- 空搜索
- 多索引和多類型
- 分頁
- 查詢字符串
- 映射和分析
- 數據類型差異
- 確切值對決全文
- 倒排索引
- 分析
- 映射
- 復合類型
- 結構化查詢
- 請求體查詢
- 結構化查詢
- 查詢與過濾
- 重要的查詢子句
- 過濾查詢
- 驗證查詢
- 結語
- 排序
- 排序
- 字符串排序
- 相關性
- 字段數據
- 分布式搜索
- 查詢階段
- 取回階段
- 搜索選項
- 掃描和滾屏
- 索引管理
- 創建刪除
- 設置
- 配置分析器
- 自定義分析器
- 映射
- 根對象
- 元數據中的source字段
- 元數據中的all字段
- 元數據中的ID字段
- 動態映射
- 自定義動態映射
- 默認映射
- 重建索引
- 別名
- 深入分片
- 使文本可以被搜索
- 動態索引
- 近實時搜索
- 持久化變更
- 合并段
- 結構化搜索
- 查詢準確值
- 組合過濾
- 查詢多個準確值
- 包含,而不是相等
- 范圍
- 處理 Null 值
- 緩存
- 過濾順序
- 全文搜索
- 匹配查詢
- 多詞查詢
- 組合查詢
- 布爾匹配
- 增加子句
- 控制分析
- 關聯失效
- 多字段搜索
- 多重查詢字符串
- 單一查詢字符串
- 最佳字段
- 最佳字段查詢調優
- 多重匹配查詢
- 最多字段查詢
- 跨字段對象查詢
- 以字段為中心查詢
- 全字段查詢
- 跨字段查詢
- 精確查詢
- 模糊匹配
- Phrase matching
- Slop
- Multi value fields
- Scoring
- Relevance
- Performance
- Shingles
- Partial_Matching
- Postcodes
- Prefix query
- Wildcard Regexp
- Match phrase prefix
- Index time
- Ngram intro
- Search as you type
- Compound words
- Relevance
- Scoring theory
- Practical scoring
- Query time boosting
- Query scoring
- Not quite not
- Ignoring TFIDF
- Function score query
- Popularity
- Boosting filtered subsets
- Random scoring
- Decay functions
- Pluggable similarities
- Conclusion
- Language intro
- Intro
- Using
- Configuring
- Language pitfalls
- One language per doc
- One language per field
- Mixed language fields
- Conclusion
- Identifying words
- Intro
- Standard analyzer
- Standard tokenizer
- ICU plugin
- ICU tokenizer
- Tidying text
- Token normalization
- Intro
- Lowercasing
- Removing diacritics
- Unicode world
- Case folding
- Character folding
- Sorting and collations
- Stemming
- Intro
- Algorithmic stemmers
- Dictionary stemmers
- Hunspell stemmer
- Choosing a stemmer
- Controlling stemming
- Stemming in situ
- Stopwords
- Intro
- Using stopwords
- Stopwords and performance
- Divide and conquer
- Phrase queries
- Common grams
- Relevance
- Synonyms
- Intro
- Using synonyms
- Synonym formats
- Expand contract
- Analysis chain
- Multi word synonyms
- Symbol synonyms
- Fuzzy matching
- Intro
- Fuzziness
- Fuzzy query
- Fuzzy match query
- Scoring fuzziness
- Phonetic matching
- Aggregations
- overview
- circuit breaker fd settings
- filtering
- facets
- docvalues
- eager
- breadth vs depth
- Conclusion
- concepts buckets
- basic example
- add metric
- nested bucket
- extra metrics
- bucket metric list
- histogram
- date histogram
- scope
- filtering
- sorting ordering
- approx intro
- cardinality
- percentiles
- sigterms intro
- sigterms
- fielddata
- analyzed vs not
- 地理坐標點
- 地理坐標點
- 通過地理坐標點過濾
- 地理坐標盒模型過濾器
- 地理距離過濾器
- 緩存地理位置過濾器
- 減少內存占用
- 按距離排序
- Geohashe
- Geohashe
- Geohashe映射
- Geohash單元過濾器
- 地理位置聚合
- 地理位置聚合
- 按距離聚合
- Geohash單元聚合器
- 范圍(邊界)聚合器
- 地理形狀
- 地理形狀
- 映射地理形狀
- 索引地理形狀
- 查詢地理形狀
- 在查詢中使用已索引的形狀
- 地理形狀的過濾與緩存
- 關系
- 關系
- 應用級別的Join操作
- 扁平化你的數據
- Top hits
- Concurrency
- Concurrency solutions
- 嵌套
- 嵌套對象
- 嵌套映射
- 嵌套查詢
- 嵌套排序
- 嵌套集合
- Parent Child
- Parent child
- Indexing parent child
- Has child
- Has parent
- Children agg
- Grandparents
- Practical considerations
- Scaling
- Shard
- Overallocation
- Kagillion shards
- Capacity planning
- Replica shards
- Multiple indices
- Index per timeframe
- Index templates
- Retiring data
- Index per user
- Shared index
- Faking it
- One big user
- Scale is not infinite
- Cluster Admin
- Marvel
- Health
- Node stats
- Other stats
- Deployment
- hardware
- other
- config
- dont touch
- heap
- file descriptors
- conclusion
- cluster settings
- Post Deployment
- dynamic settings
- logging
- indexing perf
- rolling restart
- backup
- restore
- conclusion