#### 跨域查詢(Cross-fields Queries)
如果你在索引文檔前就能夠自定義_all字段的話,那么使用_all字段就是一個不錯的方法。但是,ES同時也提供了一個搜索期間的解決方案:使用類型為cross_fields的multi_match查詢。cross_fields類型采用了一種以詞條為中心(Term-centric)的方法,這種方法和best_fields及most_fields采用的以字段為中心(Field-centric)的方法有很大的區別。它將所有的字段視為一個大的字段,然后在任一字段中搜索每個詞條。
為了闡述以字段為中心和以詞條為中心的查詢的區別,看看以字段為中心的most_fields查詢的解釋(譯注:通過validate-query API得到):
```Javascript
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and", <1>
"fields": [ "first_name", "last_name" ]
}
}
}
```
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> operator設為了and,表示所有的詞條都需要出現。
對于一份匹配的文檔,peter和smith兩個詞條都需要出現在相同的字段中,要么是first_name字段,要么是last_name字段:
(+first_name:peter +first_name:smith)
(+last_name:peter +last_name:smith)
而以詞條為中心的方法則使用了下面這種邏輯:
+(first_name:peter last_name:peter)
+(first_name:smith last_name:smith)
換言之,詞條peter必須出現在任一字段中,同時詞條smith也必須出現在任一字段中。
cross_fields類型首先會解析查詢字符串來得到一個詞條列表,然后在任一字段中搜索每個詞條。僅這個區別就能夠解決在以字段為中心的查詢中提到的3個問題中的2個,只剩下倒排文檔頻度的不同這一問題。
幸運的是,cross_fields類型也解決了這個問題,從下面的validate-query請求中可以看到:
```Javascript
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields", <1>
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
```
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> `cross_fields` 使用以詞條為中心(Term-centric)進行匹配。
它通過混合(Blending)字段的倒排文檔頻度來解決詞條頻度的問題:
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
換言之,它會查找詞條smith在first_name和last_name字段中的IDF值,然后使用兩者中較小的作為兩個字段最終的IDF值。因為smith是一個常見的姓氏,意味著它也會被當做一個常見的名字。
> 提示:為了讓cross_fields查詢類型能以最佳的方式工作,所有的字段都需要使用相同的解析器。使用了相同的解析器的字段會被組合在一起形成混合字段(Blended Fields)。
如果你包含了使用不同解析鏈(Analysis Chain)的字段,它們會以和best_fields相同的方式被添加到查詢中。比如,如果我們將title字段添加到之前的查詢中(假設它使用了一個不同的解析器),得到的解釋如下所示:
(+title:peter +title:smith)
(
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
)
當使用了minimum_should_match以及operator參數時,這一點尤為重要。
#### 逐字段加權(Per-field Boosting)
使用cross_fields查詢相比使用[自定義_all字段](../110_Multi_Field_Search/45_Custom_all.md)的一個優點是你能夠在查詢期間對個別字段進行加權。
對于first_name和last_name這類擁有近似值的字段,也許加權是不必要的,但是如果你通過title和description字段來搜索書籍,那么你或許會給予title字段更多的權重。這可以通過前面介紹的caret(^)語法來完成:
```Javascript
GET /books/_search
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title^2", "description" ] <1>
}
}
}
```
<1> The `title` field has a boost of `2`, while the `description` field
has the default boost of `1`.
能夠對個別字段進行加權帶來的優勢應該和對多個字段執行查詢伴隨的代價進行權衡,因為如果使用自定義的_all字段,那么只需要要對一個字段進行查詢。選擇能夠給你帶來最大收益的方案。
<!--
=== cross-fields Queries
The custom `_all` approach is a good solution, as long as you thought
about setting it up before you indexed your((("multifield search", "cross-fields queries")))((("cross-fields queries"))) documents. However, Elasticsearch
also provides a search-time solution to the problem: the `multi_match` query
with type `cross_fields`.((("multi_match queries", "cross_fields type")))
The `cross_fields` type takes a term-centric approach, quite different from the
field-centric approach taken by `best_fields` and `most_fields`. It treats all
of the fields as one big field, and looks for _each term_ in _any field_.
To illustrate the difference between field-centric and term-centric queries,
look at ((("field-centric queries", "differences between term-centric queries and")))((("most fields queries", "explanation for field-centric approach")))the `explanation` for this field-centric `most_fields` query:
[source,js]
--------------------------------------------------
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and", <1>
"fields": [ "first_name", "last_name" ]
}
}
}
--------------------------------------------------
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> All terms are required.
For a document to match, both `peter` and `smith` must appear in the same
field, either the `first_name` field or the `last_name` field:
(+first_name:peter +first_name:smith)
(+last_name:peter +last_name:smith)
A _term-centric_ approach would use this logic instead:
+(first_name:peter last_name:peter)
+(first_name:smith last_name:smith)
In other words, the term `peter` must appear in either field, and the term
`smith` must appear in either field.
The `cross_fields` type first analyzes the query string to produce a list of
terms, and then it searches for each term in any field. That difference alone
solves two of the three problems that we listed in <<field-centric>>, leaving
us just with the issue of differing inverse document frequencies.
Fortunately, the `cross_fields` type solves this too, as can be seen from this
`validate-query` request:
[source,js]
--------------------------------------------------
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields", <1>
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
--------------------------------------------------
// SENSE: 110_Multi_Field_Search/50_Cross_field.json
<1> Use `cross_fields` term-centric matching.
It solves the term-frequency problem by _blending_ inverse document
frequencies across fields: ((("cross-fields queries", "blending inverse document frequencies across fields")))((("inverse document frequency", "blending across fields in cross-fields queries")))
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
In other words, it looks up the IDF of `smith` in both the `first_name` and
the `last_name` fields and uses the minimum of the two as the IDF for both
fields. The fact that `smith` is a common last name means that it will be
treated as a common first name too.
[NOTE]
==================================================
For the `cross_fields` query type to work optimally, all fields should have
the same analyzer.((("analyzers", "in cross-fields queries")))((("cross-fields queries", "analyzers in"))) Fields that share an analyzer are grouped together as
blended fields.
If you include fields with a different analysis chain, they will be added to
the query in the same way as for `best_fields`. For instance, if we added the
`title` field to the preceding query (assuming it uses a different analyzer), the
explanation would be as follows:
(+title:peter +title:smith)
(
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
)
This is particularly important when using the `minimum_should_match` and
`operator` parameters.
==================================================
==== Per-Field Boosting
One of the advantages of using the `cross_fields` query over
<<custom-all,custom `_all` fields>> is that you ((("cross-fields queries", "per-field boosting")))((("boosting", "per-field boosting in cross-fields queries")))can boost individual
fields at query time.
For fields of equal value like `first_name` and `last_name`, this generally
isn't required, but if you were searching for books using the `title` and
`description` fields, you might want to give more weight to the `title` field.
This can be done as described before with the caret (`^`) syntax:
[source,js]
--------------------------------------------------
GET /books/_search
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title^2", "description" ] <1>
}
}
}
--------------------------------------------------
<1> The `title` field has a boost of `2`, while the `description` field
has the default boost of `1`.
The advantage of being able to boost individual fields should be weighed
against the cost of querying multiple fields instead of querying a single
custom `_all` field. Use whichever of the two solutions that delivers the most
bang for your buck.
-->
- 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