### 查找准确值
对于准确值,你需要使用过滤器。过滤器的重要性在于它们非常的快。它们不计算相关性(避过所有计分阶段)而且很容易被缓存。我们今后再来讨论过滤器的性能优势【过滤器缓存】,现在,请先记住尽可能多的使用过滤器。
#### 用于数字的 `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