Neil Zhu,简书ID Not_GOD,University AI 创始人 & Chief Scientist,致力于推进世界人工智能化进程。制定并实施 UAI 中长期增长战略和目标,带领团队快速成长为人工智能领域最专业的力量。
作为行业领导者,他和UAI一起在2014年创建了TASA(中国最早的人工智能社团), DL Center(深度学习知识中心全球价值网络),AI growth(行业智库培训)等,为中国的人工智能人才建设输送了大量的血液和养分。此外,他还参与或者举办过各类国际性的人工智能峰会和活动,产生了巨大的影响力,书写了60万字的人工智能精品技术内容,生产翻译了全球第一本深度学习入门书《神经网络与深度学习》,生产的内容被大量的专业垂直公众号和媒体转载与连载。曾经受邀为国内顶尖大学制定人工智能学习规划和教授人工智能前沿课程,均受学生和老师好评。
Query DSL
elasticsearch提供了一整套机遇JSON的查询DSL语言来定义查询。一般来说,会包含基本的term和前缀查询。同样也包含复合查询如bool查询。查询也拥有过滤器,诸如filtered或者constant_score的查询(以特定的过滤查询)。
请将查询DSL当作查询的一个抽象语法树(AST)。某些查询可以包含其他的查询(例如bool查询),另外一些则包含过滤器(如constant_score),还有就是包含两者的(如filtered)。这些查询都可以包含查询列表种的任意的查询,或者任何过滤器列表种的一个。这样就能够构建出相当复杂的(和有趣的)查询。
查询和过滤器都可以在不同的API里使用。例如,在一个搜索查询,或者作为一个facet filter。这个章节解释了查询和过滤两个部分,从而可以形成可以使用的抽象语法树(AST)。
由于没有打分的过程,并且自动的cache,所以过滤器比一般查询降低超过一个数量级,因此它们是相当好用的。
Queries
按照一个通用的规则,查询应当尽可能被过滤器所替代:
- 全文检索
- 结果依赖于一个相关性的打分
match查询
match查询接受文本/数值/日期,分析之,构造出一个查询。例如:
{
"match" : {
"message" : "This is a test"
}
}
注意,message
是field的名称,可以使用任何一个field的名称来代替(包含_all
)。
match查询的类型
boolean
boolean 默认的match
查询就是布尔型(boolean),这是指对目标文本进行分析,分析后便构造出一个布尔查询。operator
标记可以被设置为or
或者and
来控制布尔语句(默认为or
)。should
语句最小值可以使用minimum_should_match
参数来设置。
analyzer
可以被设置来控制分析器(analyzer)将要执行的对文本的分析过程。默认被设为field显式的mapping定义或者默认搜索分析器。
fuzziness
允许fuzzy matching基于被查询的field的类型。见Fuzziness那章。
prefix_length
和max_expansions
可以被设置来控制fuzzy过程。如果fuzzy选项被设置,那么查询会使用constant_score_rewrite
作为其重写方法(rewrite method)的参数。fuzzy_rewrite
参数允许控制查询的如何被重写。
下面是一个提供了额外参数的(注意其结构的微妙——变化message
是field名称)例子:
{
"match" : {
"message" : {
"query" : "this is a test",
"operator" : "and"
}
}
}
zero_terms_query
:如果使用的analyzer移除了一个查询中所有的token(如stop filter所做的那样),默认行为是不匹配任何文章。为了改变使得zero_terms_query
选项可以被使用,其接受none
(默认)和all
对应于match_all
查询。
{
"match" : {
"message" : {
"query" : "to be or not to be",
"operator" : "and",
"zero_terms_query": "all"
}
}
}
cutoff_frequency
允许设置一个绝对或者相对的文档频率,其中高频项被移进一个可选的子查询,并且当使用or
连接的低频项的一个或者所有用and
相连的低频项匹配时记分。
这种查询可以在运行时动态处理stopwords
,并且是domain独立的,也并不要求一个停词文件。阻止打分/迭代高频term和只有一个更加明显/低频term匹配一个文档时才会考虑这些term。但是,如果所有查询term超过给定的cutoff_frequency
,查询自动转化为一个纯合取(and
)查询来确保快速执行。
cutoff_frequency
如果在[0..1)
区间中,则与index中的文档数相关。如果超过1.0
,则为绝对值。
下面是展示包含stopwords的查询
{
"match" : {
"message" : {
"query" : "to be or not to be",
"cutoff_frequency" : 0.001
}
}
}
phrase
match_phrase
查询分析文本并从分析了的文本中创建一个phrase
查询。例如:
{
"match_phrase" : {
"message" : "This is a test"
}
}
由于match_phrase
仅是match
查询的一种type
,它可以如下使用:
{
"match" : {
"message" : {
"query" : "this is a test",
"type" : "phrase"
}
}
}
phrase查询匹配可设置的任意顺序的slop
(默认为0)个数的term。Transposed term拥有2的slop。
analyzer
可以被设置来控制那个分析器来执行对文本的分析过程。默认为field显式的mapping定义,或者默认的搜索分析器,例如:
{
"match_phrase" : {
"message" : {
"query" : "this is a test",
"analyzer" : "my_analyzer"
}
}
}
match_phrase_prefix
match_phrase_prefix
与match_phrase
相同,除了它允许前缀匹配。except that it allows for prefix matches on the last term in the text.
{
"match_phrase_prefix" : {
"message" : "this is a test"
}
}
或:
{
"match" : {
"message" : {
"query" : "this is a test",
"type" : "phrase_prefix"
}
}
}
它接受同样的参数作为phrase type。另外,它同样接受max_expansions
参数,该参数可以控制最后项将要被扩展的前缀的个数。强烈建议将其设置为一个可接受的值来空查询的执行时间。例如:
{
"match_phrase_prefix" : {
"message" : {
"query" : "this is a test",
"max_expansions" : 10
}
}
}
与query_string/field的比较
查询的匹配(match)家族并不会走“查询parsing”的过程。并不支持field名的前缀,wildcard字符或者其他高级特性。因此,它失败的几率非常小/或者完全不会出现,并且当仅需要分析和运行一个文本作为查询行为(text search box常常这么干)。另外,phrase_prefix
类型可以提供一个“as you type”行为来自动加载搜索结果。
其余选项
- lenient - 如设置为
true
将会导致基于格式的失败(例如提供文本给一个数值类型的field)被忽略。默认为false
。
multi match query
多重匹配查询建立在match
查询的基础上:
{
"multi_match" : {
"query": "this is a test", ..... 1
"fields": [ "subject", "message" ] ..... 2
}
}
- 查询词
- 查询的域
fields
和每个field的boosting
fields可以使用通配符(wildcards),如:
{
"multi_match" : {
"query" : "Will Smith",
"fields" : ["title", "*_name"] ..... 1
}
}
- 查询
title
、first_name
和last_name
field。
独立的field可以使用caret(^)符号进行增加额度:
{
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^3", "messsage" ] .....1
}
}
use_dis_max
1.1.0中反对使用。使用
type:best_fields
和type:most_fields
代替。见multi_match查询
默认,multi_match
查询对每个field均生成了一个match
子句,接着将这些子句包含进一个dis_max
查询。通过设置use_dis_max
为false
,他们将被包含进一个bool
查询而非dis_max
查询。
multi_match查询的types
在1.1.0中添加
multi_match
查询的执行过程依赖于type
参数,该参数可以被设置为:
- best_fields -(默认)找出匹配任何field的文档,但是使用来自best field的
_score
。见best_fields
- most_fields - 找出匹配任何field并且合并来自每个field的
_score
。见most_fields
- cross_fields - 将拥有相同
analyzer
的field当作一个大的field。查找在任何field中的每个word。见cross_fields
- phrase - 对每个field上运行一个
match_phrase
查询并合并来自每个field的_score
。参见phrase
和phrase_prefix
- phrase_prefix - 在每个field上运行一个
match_phrase_prefix
查询并合并来自每个field的_score
。参见phrase
和phrase_prefix
best_fields
best_fields
类型是当你搜索在同样的field中多个word时最有用的。The best_fields type is most useful when you are searching for multiple words best found in the same field. 例如,“brown fox”在一个单一field比“brown”在一个field而“fox”在另一个field中更有可能。
best_fields
类型对每个field均生成一个match_query
,将他们包含在一个dis_max
查询中,来找到单一的最佳匹配field。例如,下面这个查询:
{
"multi_match" : {
"query" : "brown fox",
"type" : "best_fields",
"fields" : ["subject", "message"],
"tie_breaker" : 0.3
}
}
将会被执行为以下查询:
{
"dis_max": {
"queries": [
{ "match": { "subject": "brown fox" }},
{ "match": { "message": "brown fox" }}
],
"tie_breaker": 0.3
}
}
正常来说,best_fields
类型使用单一最有匹配field的打分,但是如果tie_breaker
被指定,那么它会以如下方式计算打分:
- 分数来自最优匹配field
- 加上来自其他匹配field的
tie_breaker * _score
同样,接受analyzer, boost, operator, minimum_should_match, fuzziness, prefix_length, max_expansions, rewrite, zero_terms_query and cutoff_frequency
,这些在match query中已经解释过了。
operator
和minimum_should_match
这两个类型是以field为中心的——他们对每个field产生一个match
查询。这是指operator
和minimum_should_match
参数被独立地应用在每个field上,这可能不是你本来想要的效果
例如:{ "multi_match" : { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" ..... 1 } }
- 要求所有项都要出现
这个查询就执行为:
(+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
也就是说,所有term必须在一个单一的field中以匹配一篇文档
most_fields
most_fields
类型是在查询多个field包含以不同方式分析的同样的文本时最为有效。例如,main field可能会包含同义词、stemming和不包含变音符的项(term)第二field可能包含原始term,第三field可能包含“招牌”。通过合并来自所有这三个field的分数,我们可以匹配主field的尽可能多的文档,但是使用第二和第三个field来推送最相似的结果到返回列表的list。
下面的这个查询:
{
"multi_match" : {
"query": "quick brown fox",
"type": "most_fields",
"fields": [ "title", "title.original", "title.shingles" ]
}
}
将被执行为:
{
"bool": {
"should": [
{ "match": { "title": "quick brown fox" }},
{ "match": { "title.original": "quick brown fox" }},
{ "match": { "title.shingles": "quick brown fox" }}
]
}
}
来自每个match
子句的分数将被加起来,然后初上match
子句的数目。
同样的,它也接受analyzer, boost, operator, minimum_should_match, fuzziness, prefix_length, max_expansions, rewrite, zero_terms_query and cutoff_frequency
,这些在match query中已经解释过了。
phrase和phrase_prefix
phrase
和phrase_prefix
类型和best_fields
行为类似,但是他们使用了一个match_phrase
或match_phrase_prefix
查询而不是一个match
查询。
这个查询:
{
"multi_match" : {
"query": "quick brown f",
"type": "phrase_prefix",
"fields": [ "subject", "message" ]
}
}
就如同:
{
"dis_max": {
"queries": [
{ "match_phrase_prefix": { "subject": "quick brown f" }},
{ "match_phrase_prefix": { "message": "quick brown f" }}
]
}
}
同样,它接受analyzer``boost``slop``zero_terms_query
,这些在match query中已经解释过了。phrase_prefix
额外接受max_expansions
。
cross_fields
cross_field
类型特别是在遇到结构化文档并且多个field应当match时尤为好用。例如,当查询first_name
和last_name
field“Will Smith”时,best match可能会将“Will”放在一个field中,而把“Smith”放进另一个。
这就如同
most_fields
那样,但是有两个问题。一个问题是operator
和minimum_should_match
是按每field进行的,而不是每个term。
第二个问题与相关性有关系:不同的term频率在first_name
和last_name
field可以产生难以预料的结果。
例如,假设我们有两个人“Will Smith”和“Smith Jones”。“Smith”作为一个last name是相当普通的(所以就会降低其重要性),但是“Smith”作为一个first name是罕见的(因此就给它较大的重要性)。
如果我们搜索“Will Smith”,“Smith Jones”文档将出现在更好的匹配“Will Smith”的结果中,因为first_name:smith
的分数已经超过合并后的first_name:will
加上last_name:smith
的分数。
一种解决这些查询类型的方法是简单地索引first_name
和last_name
fields进一个单一的full_name
field。当然,这只能在索引过程中完成。
cross_field
类型试着解决这些问题在查询时刻,通过使用以term为中心的方法。它首先解析查询string为单个的term,接着在任何field中查找每个term,就如同他们是在一个大的field进行一样。
如下的查询:
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
被执行为:
+(first_name:will last_name:will)
+(first_name:smith last_name:smith)
换句话说,所有term都必须放在至少一个field中以让文档匹配到。(与best_fields和most_fields进行比较)
这解决了两个问题中的一个。让term frequencies的差异通过混合对所有field项的频率来屏蔽差异完成。换句话说,first_name:smith
将被看作它有与last_name:smith
相同的权值。(事实上,first_name:smith
比起last_name:smith
有一点点优势,会让结果的顺序更加稳定一些)
如果你通过调用Validate API
运行上述查询,它将返回下面的解释:
+blended("will", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])
同样的,它也会接受match query中介绍过的analyzer, boost, operator, minimum_should_match, zero_terms_query and cutoff_frequency
cross_field
和analysis
cross_field
类型可以仅对拥有相同的分析器的field在以term为中心的模式下进行工作。拥有相同分析器的field常被像上面例子里那样组合起来。
如果有多个群组(group),他们将被一个bool
查询包含起来。
例如,如果我们有一个first
和last
field,都有相同的分析器,加上一个first.edge
和last.edge
,两者都使用edge_ngram
分析器,这个查询:
{
"multi_match" : {
"query": "Jon",
"type": "cross_fields",
"fields": [
"first", "first.edge",
"last", "last.edge"
]
}
}
将被执行为:
blended("jon", fields: [first, last])
| (
blended("j", fields: [first.edge, last.edge])
blended("jo", fields: [first.edge, last.edge])
blended("jon", fields: [first.edge, last.edge])
)
换句话说,first
和last
可能会被组合起来作为一个单一的field,并且first.edge
和last.edge
也同样被组合起来当作一个单一的field。
拥有多个group很好,不过当和operator
或minimum_should_match
组合时,就可能会遇到most_fields
和best_fields
那样的问题。
你可以轻易重写这个查询以两个分开的cross_type
查询与一个bool
查询,然后应用minimum_should_match
参数到其中一个上面:
{
"bool": {
"should": [
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first", "last" ],
"minimum_should_match": "50%" ..... 1
}
},
{
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "*.edge" ]
}
}
]
}
}
- will或者smith肯定要出现在first或者lastfield中的一个中。
你可以强迫所有field在一个群组中,通过设置查询中的analyzer参数:
{
"multi_match" : {
"query": "Jon",
"type": "cross_fields",
"analyzer": "standard", ..... 1
"fields": [ "first", "last", "*.edge" ]
}
}
- 对所有的field均使用
standard
分析器
这个查询将按如下方式执行:
blended("will", fields: [first, first.edge, last.edge, last])
blended("smith", fields: [first, first.edge, last.edge, last])
tie_break
默认情形,每个针对term的blened
查询将使用群组中任何field的最优打分,然后这些分数加在一起来给出最终的分数。tie_breaker
参数可以改变per-term查询的默认行为。它接受参数:
-
0.0
-first_name:will
和last_name:will
中选择单一最优分数(默认) -
1.0
-将first_name:will
和last_name:will
的分数相加 -
0.0 < n < 1.0
-选出单一最优分数加上[tie_breaker
乘上每个其他匹配field的分数]
filters
exists filter
过滤其中特定field含有给定值的文档。
geo bounding box filter
基于点位置来过滤在一个限定box中位置。假设有以下索引好的文档:
{
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
那么下列简单的查询可以被一个geo_bounding_box
过滤器执行:
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.01,
"lon" : -71.12
}
}
}
}
}
}
lat
,lon
的类型
经纬度作为属性
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : {
"lat" : 40.73,
"lon" : -74.1
},
"bottom_right" : {
"lat" : 40.01,
"lon" : -71.12
}
}
}
}
}
}
经纬度作为数组
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : [-74.1, 40.73],
"bottom_right" : [-71.12, 40.01]
}
}
}
}
}
经纬度作为string
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : "40.73, -74.1",
"bottom_right" : "40.01, -71.12"
}
}
}
}
}
地理信息hash
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top_left" : "dr5r9ydj2y73",
"bottom_right" : "drj7teegpus6"
}
}
}
}
}
顶点(vertices)
除了以上的方法外还可以直接设置每个顶点的位置值
地理点类型
过滤器要求geo_point
类型被设置在相关的field上
文档中多个位置
过滤器可以与多个地理位置或者地点进行工作。一旦一个单一点与过滤器匹配,文档将被包含进过滤器中。
类型(type)
The type of the bounding box execution by default is set to memory, which means in memory checks if the doc falls within the bounding box range.
约束的box的类型被默认设置为memory。。。
某些时候,一个被索引过的选项执行得更快速(但是注意geo_point
类型肯定需要有被索引的lat和lon)。注意当使用索引过的选项时,文档field中多个位置不被支持。
caching
过滤的结果默认不被缓存。_cache
可以被设为true
来缓存过滤的结果。这相当好用尤其时相同的bounding box参数被用于其他查询的时候。注意,caching首次执行的过程更高一些,因为需要满足不同的查询。
geo distance filter
过滤哪些位于离一个给定geopoint的一个特定距离内的文档。假设有如下已经索引的json:
{
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
}
}
那么下列简单查询可以执行一个geo_distance
过滤器:
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_distance" : {
"distance" : "200km",
"pin.location" : {
"lat" : 40,
"lon" : -70
}
}
}
}
}
可接受的格式
和geo_point
类型差不多
lat lon作为属性
lat lon作为数组
lat lon作为string
geohash
选项
下列为filter可以使用的选项
-
distance
特定地点的半径,落在此圆内的点都被匹配。这个距离可以设置不同的单位。见距离单位 -
distance_type
如何计算距离,可选择arc
(精度最高)、sloppy_arc
(快速,精度略少)和plane
(最快)。默认为sloppy_arc
。 -
optimize_bbox
是否在距离check之前使用首次执行bound box check。默认设置为memory
将在内存中进行check。同样也可以设置indexed
从而使用索引后的值检查(需要保证geo_point
类型为index lat lon)
geo_point type
multi location per document
caching
geo distance range filter
Filters documents that exists within a range from a specific point:
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_distance_range" : {
"from" : "200km",
"to" : "400km"
"pin.location" : {
"lat" : 40,
"lon" : -70
}
}
}
}
}
Supports the same point location parameter as the geo_distance filter. And also support the common parameters for range (lt, lte, gt, gte, from, to, include_upper and include_lower).
geoshape filter
has child filter
has_child
过滤器接受一个查询和child类型,来执行过滤,得到的结果是包含了被匹配的child doc的父文档。例如:
{
"has_child" : {
"type" : "blog_tag",
"query" : {
"term" : {
"tag" : "something"
}
}
}
}
has parent filter
has_parent
过滤器接受查询和一个父类型。查询在父文档空间执行,这是由父类型确定的。过滤器返回子文档这些文档关联的父文档被命中。对于has_parent
过滤器的剩下的选项,其设置是于has_child
过滤器一致。
filter example
{
"has_parent" : {
"parent_type" : "blog",
"query" : {
"term" : {
"tag" : "something"
}
}
}
}
这里parent_type
field名可以被简写为type
。
filter实现的方式是首先运行父查询,然后进行匹配到被匹配的每个文档的子文档。
has_parent
过滤器也接受一个过滤器作为查询的参数。
{
"has_parent" : {
"type" : "blog",
"filter" : {
"term" : {
"text" : "bonsai three"
}
}
}
}
内存
为了支持父子的join(连接),所有父ID必须常驻内存(在field数据缓存中)。另外,每个子文档被映射到它的父文档,使用一个long值(近似的)。建议保持string类型的父ID尽可能短来歼敌内存的使用。
你可以使用indices stats
和nodes
API来检查有多少内存已经被ID缓存所占用,如:
curl -XGET "http://localhost:9200/_stats/id_cache?pretty&human"
caching
has_parent
过滤器不能在filter cache中cache。_cache
和_cache_key
选项在此filter中是no-op。同样任何过滤器包含了has_parent
,无论是直接还是间接,都不会被cache。
ids filter
过滤哪些仅有提供的id的文档。注意,这个过滤器不要求_id
field被索引,因为它只需要使用_uid
就可以了。
{
"ids" : {
"type" : "my_type",
"values" : ["1", "4", "100"]
}
}
type
是可选的,也可以被省略,并且也能接受一个值的数组。
indices filter
indices
过滤器可以在执行多个indices时候使用,允许有一个过滤器执行匹配一个特定的索引的list,另一个在一个索引上执行匹配词之外的索引。
当然你可以使用index
field来提供一个单一的index。
no_match_filter
可以用none作为"string"的值(不匹配任何文档),all
(匹配所有)
filter
是强制的,如同indices
(或index
)
field的顺序是重要的:如果
indices
在filter
或no_match_filter
之前出现,那么关联的过滤器只有在将要执行的indices上进行parse。没有必要,避免潜在映射错误。
script filter
可以定义脚本的过滤器,例如:
"filtered" : {
"query" : {
...
},
"filter" : {
"script" : {
"script" : "doc['num1'].value > 1"
}
}
}
custom parameters
为了更快的执行,脚本进行编译和缓存。如果相同的脚本被调用而只是参数的不同,那么建议使用可以传递参数的脚本。例如:
"filtered" : {
"query" : {
...
},
"filter" : {
"script" : {
"script" : "doc['num1'].value > param1"
"**params**" : {
"param1" : 5
}
}
}
}
caching
过滤器的结果默认并不会被缓存,_cache
可被设置为true
来缓存过滤器的结果。当我们要使用好多次相同的代码时尤其好用。注意缓存的过程
mapping
映射时定义一个文档该如何被映射到搜索引擎的过程,包含它可搜索的特征诸如哪些field可以搜索到,还有是否它们被tokenized。在ES中,一个索引可能存储不同的“映射类型”。ES允许人们关联多个mapping定义对每个mapping类型。
显式的mapping定义在index/type层面。默认对于定义一个显式的mapping是没有需求的,因为mapping是自动创建和注册,当一个新的类型或者field被引入,而是mapping是有敏感的默认设置的。仅当默认需要被重写时,mapping的定义才需要提供。
mapping types
mapping types时一种分割一个索引的文档成逻辑组的方式。就把它当成数据库中的表吧。尽管type间有分割,这不是一种全分割(所有的最终更逗在同样的Lucene索引下。)
type之间相同的名称的field名强烈建议有 相同的type和相同的mapping特征(例如分析设置)。There is an effort to allow to explicitly "choose" which field to use by using type prefix (my_type.my_field), but it’s not complete, and there are places where it will never work (like faceting on the field).
然后在实际应用中,这个要求几乎不成为问题。field名经常成为其typeness的暗示。(如first_name总是一个string)。注意,这个并不适用于交叉索引的情形。
mapping api
为了创建一个mapping,你需要Put Mapping API,或者你可以添加多个mapping当你创建index时。
global settings
index.mapping.ignore_malformed
全局设置可以设置在index层面来允许全局忽视malformed内容(畸形的内容例子是试着将一个文本string值所因为一个数值类型。)
index.mapping.coerce
全局设置可以被设置在index层来强迫所有的mapping类型数值内容
(默认设置为true并切coercion)