keyword用于索引结构化内容的字段,例如电子邮件地址,主机名,状态码,邮政编码或标签。
一般用于过滤(找到个人全部博客文章,其中 status为published),排序,和聚合。keyword类型的字段只能按其准确值进行搜索。text是用于全文检索的数据类型,存储时会经过分词器对数据进行分词存储,搜索时会对分词后的多个短语进行搜索。text类型不适用用于排序和聚合。java
Elasticsearch提供了date类型来处理日期,可是因为JSON是没有日期类型的,因此在内部日期被转换为UTC而且存储为时间戳(带毫秒)。
插入日期时若是插入的为常规日期格式(yyyy-MM-dd
或者yyyy-MM-dd'T'HH:mm:ss.SSSZ
),es会自动识别日期格式,将字段类型设置为Date
。若是mapping中字段类型已经肯定为Date
,此时插入格式化日期字符串或者时间戳(字符串和Numeric
类型)时都会被Es做为日期类型存储,只不过在数据显示上和存储时的格式一致(存时间戳返回就是时间戳,字符串返回就是字符串,可是推荐存标准化的UTC时间或时间戳,避免类型不一致)。json
A:Elasticsearch默认为UTC时间,即零时区,查询时若不指定时区,则默认以0时区查询,和咱们所在的东八区差8小时。yyyy-MM-dd'T'HH:mm:ss.SSSZ
,这里的Z
就表明UTC时区。
Es在进行日期查询/聚合时能够指定时区:数组
//日期范围查询 POST datatypetest/_search { "query": { "range": { "date3": { "gte": "2018-07-05", "lte": "now", "time_zone": "Asia/Shanghai"//这就是东八区(北京时间/中国标准时间) } } } }
//日期聚合 GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day", "time_zone": "Asia/Shanghai" } } } }
//Java获取系统时区id TimeZone.getDefault().getID()
//Es Java Api日期范围查询 QueryBuilders .rangeQuery("your date field") .gte("your date from") .lte("your date to") .timeZone(TimeZone.getDefault().getID());//此处只能设置时区id
//Es Java Api日期聚合查询 AggregationBuilders .dateHistogram("your alias") .timeZone(DateTimeZone.getDefault());//获取系统默认时区,此处timeZone对象是joda包中的DateTimeZone
在使用Kibana时,Kibana会默认获取浏览器时区,在显示数据时根据时区作日期的格式化。但使用DevTools写DSL或者直接请求Es时默认返回的都是UTC时间,会发现时间少了8小时。浏览器
使用日期类型时推荐不修改日期格式时区,全部数据都用UTC时区,这样时间统一才不容易出问题。缓存
object为es的默认对象类型,嵌套的json对象存入es就会被默认设置为object类型。es内部会将嵌套的json对象扁平化转换存储。
例如,一个普通的jsonapp
{ "region": "US", "manager": { "age": 30, "name": { "first": "John", "last": "Smith" } } }
在es内部会被转换为扁平化的基础json数据post
{ "region": "US", "manager.age": 30, "manager.name.first": "John", "manager.name.last": "Smith" }
nested用于JSON对象的数组,它容许对象数组以可彼此独立查询的方式进行索引。因为lucene没有内部对象的概念,所以es须要把数据转换为简单的扁平化结构。
一个对象数组嵌套:性能
{ "group" : "fans", "user" : [ { "first" : "John", "last" : "Smith" }, { "first" : "Alice", "last" : "White" } ] }
在es内部会被转换为:ui
{ "group" : "fans", "user.first" : [ "alice", "john" ], "user.last" : [ "smith", "white" ] }
user.first和user.last字段被转换为多值字段,数据之间的关联性就会丢失,致使查询结果有误。
此时用nested类型就能够解决此问题。编码
term为精确匹配,查询时不对关键词进行分词。而match用于全文检索,首先会对检索关键词进行分词,而后进行全文搜索。
must为查询上下文(query context),查询时会计算分值(文档相关性)。filter为过滤上下文,查询时不计算分值。而post_filter为后置过滤器,会对聚合的结果也进行过滤。执行顺序为:filter -> aggregations - post_filter。
must/should为查询上下文。filter或must_not在参数 bool的查询中/filter在constant_score的查询/filter aggretion这些场景中为过滤上下文。查询上下文会计算返回文档的分值,而过滤上下文不计算分值,语义只是此文档是否匹配,而不计算相关度。在过滤上下文时,es会自动对过滤器进行缓存从而提升查询性能。