当你经常进行搜索操作时,会发现一些奇怪的事情。例如,我现在ElasticSearch中的csdn
索引、blog
类型中有这么一条数据:
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 20,
"successful" : 20,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "csdn",
"_type" : "blog",
"_id" : "124",
"_score" : 1.0,
"_source" : {
"date" : "2017-10-19"
}
}
]
}
}
接下来我们分别进行如下搜索:
①. curl -XGET 'http://localhost:9200/csdn/blog/_search?q=2017'
②. curl -XGET 'http://localhost:9200/csdn/blog/_search?q=date:2017-10-19'
③. curl -XGET 'http://localhost:9200/csdn/blog/_search?q=date:2017'
搜出结果:
①. 搜出1个文档
②. 搜出1个文档
③. 搜出0个文档
1号搜索为搜索全文,因为date
字段中包含了2017
,所以搜索出1个结果,2号搜索在date
字段中进行匹配,从数据中可以看出,所以匹配到1个的结果也是毫无问题的。再来看3号搜索,从数据可以看出,date
字段是包含2017
的,可是为何搜索却未匹配到任何文档?
这是因为ElasticSearch动态的为我们产生了映射,告诉我们date
字段是date
类型,那到底是不是这样呢,我们可以通过如下请求查看字段映射后的类型:
# 查询csdn索引,blog类型的映射
curl -XGET 'http://localhost:9200/csdn/_mapping/blog'
返回结果如下:
{
"csdn" : {
"mappings" : {
"blog" : {
"properties" : {
"date" : { "type" : "date" } }
}
}
}
}
从数据可以看出ElasticSearch动态字段做了一个映射,告诉我们date
字段是date
类型的,因为date
类型和text
索引方式不同,所以搜索的结果自然也就不一样。因为_all
是默认字段,所以没有提及它。但是我们知道_all
字段是 text
类型的。你可能会认为核心数据text
、integer
、date
、boolean
等类型的索引方式会有稍许不同。没错,它们的确有一些不同。到目前为止最大的差异在于代表精确值
的字段和代表全文
的字段
精确值与全文
ElasticSearch的数据可以概括的分为两类:精确值
和全文
精确值
顾名思义,匹配规则要求非常严格。例如日期与ID,但有些字符串也可以表示精确值,例如身份证号码以及邮箱地址等。对于精确值来讲,hello
与Hello
是不同的,2017
与2017-10-25
是不同的。
另一方面,全文
是指文本数据,例如一篇博客的内容或者一封邮件的内容等。
精确值
很容易查询,一些常用的SQL就能表示:
select * from table where name = "laowang"
select * from table where age = 18
全文
类型的搜索有点类似于我们常用的模糊查询,却又与模糊查询大不一样:
- 搜索“江南”,将会匹配到“江西”,“江苏”,“南宁”,“南昌”等
映射
为了能够将时间视为时间,数字域视为数字,字符串域视为全文或者精确值字符串,Elasticsearch需要知道每个域中数据的类型,这些数据包含在映射中。
索引中每个文档都有类型,每种类型都有它自己的映射,或者模式定义。映射定义了类型中的域,每个域的数据类型,以及Elasticsearch如何处理这些域。映射也配置与类型相关的元数据。
当前索引一个包含新域的文档–之前未曾出现过–Elasticsearch会使用动态映射
,通过JSON数据类型,尝试猜测域类型,使用如下规则:
JSON类型 | 域类型 |
---|---|
布尔型:true或者false | boolean |
整数:123 | long |
浮点型:12.3 | double |
有效日期:2017-10-29 | date |
字符串:elasticsearch | text |