[Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段
自定义_all字段
在元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引。尽管将所有字段的值作为一个字段进行索引并不是非常灵活。如果有一个自定义的_all字段用来索引人名,另外一个自定义的_all字段用来索引地址就更好了。
ES通过字段映射中的copy_to参数向我们提供了这一功能:
PUT /my_index
{
"mappings": {
"person": {
"properties": {
"first_name": {
"type": "string",
"copy_to": "full_name"
},
"last_name": {
"type": "string",
"copy_to": "full_name"
},
"full_name": {
"type": "string"
}
}
}
}
}
现在first_name和last_name字段中的值会被拷贝到full_name字段中。
有了这个映射,我们可以通过first_name字段查询名字,last_name字段查询姓氏,或者full_name字段查询姓氏和名字。
NOTE
first_name和last_name字段的映射和full_name字段的索引方式的无关。full_name字段会从其它两个字段中拷贝字符串的值,然后仅根据full_name字段自身的映射进行索引。
跨域查询(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得到):
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
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请求中可以看到:
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
它通过混合(Blending)字段的倒排文档频度来解决词条频度的问题:
+blended("peter", fields: [first_name, last_name]) +blended("smith", fields: [first_name, last_name])
换言之,它会查找词条smith在first_name和last_name字段中的IDF值,然后使用两者中较小的作为两个字段最终的IDF值。因为smith是一个常见的姓氏,意味着它也会被当做一个常见的名字。
NOTE
为了让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字段的一个优点是你能够在查询期间对个别字段进行提升。
对于first_name和last_name这类拥有近似值的字段,也许提升是不必要的,但是如果你通过title和description字段来搜索书籍,那么你或许会给予title字段更多的权重。这可以通过前面介绍的caret(^)语法来完成:
GET /books/_search
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title^2", "description" ]
}
}
}
能够对个别字段进行提升带来的优势应该和对多个字段执行查询伴随的代价进行权衡,因为如果使用自定义的_all字段,那么只需要要对一个字段进行查询。选择能够给你带来最大收益的方案。
精确值字段(Exact-value Fields)
在结束对于多字段查询的讨论之前的最后一个话题是作为not_analyzed类型的精确值字段。在multi_match查询中将not_analyzed字段混合到analyzed字段中是没有益处的。
原因可以通过validate-query进行简单地验证,假设我们将title字段设置为not_analyzed:
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title", "first_name", "last_name" ]
}
}
}
因为title字段时没有被解析的,它会以将整个查询字符串作为一个词条进行搜索!
title:peter smith ( blended("peter", fields: [first_name, last_name]) blended("smith", fields: [first_name, last_name]) )
很显然该词条在title字段的倒排索引中并不存在,因此永远不可能被找到。在multi_match查询中避免使用not_analyzed字段。
[Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段的更多相关文章
- Springboot如何优雅的解决ajax+自定义headers的跨域请求
1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...
- Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]
1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...
- 前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库
一.axios Vue更新到2.0之后宣告不再对vue-resource更新,推荐使用axios,axios是一个用于客户端与服务器通信的组件,axios 是一个基于Promise 用于浏览器和 no ...
- SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
上个示例(SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API))是基于JavaScript,运行在web browser内去访问REST AP ...
- 跨域 - 自定义 jsonp实现跨域
问题:在现代浏览器中默认是不允许跨域. 办法:通过jsonp实现跨域 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的.但是,在页面上引入不同域上的js脚本文件却是 ...
- 原创:【ajax | axios跨域简单请求+复杂请求】自定义header头Token请求Laravel5后台【亲测可用】
如标题:我想在ajax的header头增加自定义Token进行跨域api认证并调用,api使用laravel5编写,如何实现? 首先,了解下CORS简单请求和复杂请求. -- CORS简单请求 -- ...
- Elasticsearch系列---初识搜索
概要 本篇主要介绍搜索的报文结构含义.搜索超时时间的处理过程,提及了一下多索引搜索和轻量搜索,最后将精确搜索与全文搜索做了简单的对比. 空搜索 搜索API最简单的形式是不指定索引和类型的空搜索,它将返 ...
- Elasticsearch 全字段搜索_all,query_string查询,不进行分词
最近在使用ELasitcsearch的时候,需要用到关键字搜索,因为是全字段搜索,就需要使用_all字段的query_string进行搜索. 但是在使用的时候,遇到问题了.我们的业务并不需要分词,我在 ...
- ElasticSearch 2 (15) - 深入搜索系列之多字段搜索
ElasticSearch 2 (15) - 深入搜索系列之多字段搜索 摘要 查询很少是简单的一句话匹配(one-clause match)查询.很多时候,我们需要用相同或不同的字符串查询1个或多个字 ...
随机推荐
- 初探css3
属性选择器: 1.完全匹配的属性选择器. 就是完全匹配的字符串. [id=article]{ color:red; } 2.包含匹配选择器.包含有指定的字符串. 语法是:[attribute*=val ...
- poj_1091_跳蚤
Z城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持人会给该跳蚤发一张卡片.卡片上写有N+1个自然数.其中最后一个是M ...
- ABAP术语-Logical Lock
Logical Lock 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/03/1088323.html Program logic that ...
- 构建高可靠hadoop集群之2-机栈
本文主要参考 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/RackAwareness.html had ...
- JSP/Servlet开发——第五章 使用分层实现业务处理
1.JNDI(Java Naming and Directory Interface)Java命名和目录接口: ●JNDI:是一个有关应用序设计的 API 为开发人员提供了查找和访问各种命名和目录服务 ...
- 为什么我用了$().height()还是对不齐呢?
有一个这样的需求:有两个显示内容的框,要使他们高度一致,因为他们存放的内容多少和结构不一样,左边内容少,右边内容多.这就导致了右边会比左边高,解决方法就是超出部分用滚轮显示,那这时就先要调整右边的高度 ...
- apache使用.htaccess文件中RewriteRule重定向后,URL中的加号无法解析
今天在使用.htaccess做伪静态的时候,发生一件怪事,URL里存在C++时会有问题,在处理C++这个词的时候,无论如何,$_GET都得不到++,只能得到C空格. 一开始我以为是没用urlencod ...
- ABAP CDS ON HANA-(11)ABAP CDSでの関連付け
Association in ABAP CDS An association in CDS view joins different data sources. Defining and using ...
- 为什么我要放弃javaScript数据结构与算法(第三章)—— 栈
有两种结构类似于数组,但在添加和删除元素时更加可控,它们就是栈和队列. 第三章 栈 栈数据结构 栈是一种遵循后进先出(LIFO)原则的有序集合.新添加的或待删除的元素都保存在栈的同一端,称为栈顶,另一 ...
- android staido 断点遇到的坑
今天排查数据布点问题,发现sd卡上面的文件莫名消失. 怎么可能?系统不可能删除你的文件,但是我调试,删除文件的代码, 一直都没有执行啊. 后来发现,子线程里面代码,android stadio 可能断 ...