博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Elasticsearch 的一些常见疑问(持续更新中)
阅读量:7256 次
发布时间:2019-06-29

本文共 2899 字,大约阅读时间需要 9 分钟。

数据类型

keyword和text有什么区别?

keyword用于索引结构化内容的字段,例如电子邮件地址,主机名,状态码,邮政编码或标签。

通常用于过滤(找到我的所有博客文章,其中 status为published),排序,和聚合。keyword类型的字段只能按其准确值进行搜索。text是用于全文检索的数据类型,存储时会通过分词器对数据进行分词存储,搜索时会对分词后的多个短语进行搜索。text类型不适用用于排序和聚合。

日期类型

Elasticsearch提供了date类型来处理日期,但是由于JSON是没有日期类型的,所以在内部日期被转换为UTC并且存储为时间戳(带毫秒)。

插入日期时如果插入的为常规日期格式(yyyy-MM-dd或者yyyy-MM-dd'T'HH:mm:ss.SSSZ),es会自动识别日期格式,将字段类型设置为Date。如果mapping中字段类型已经确定为Date,此时插入格式化日期字符串或者时间戳(字符串和Numeric类型)时都会被Es作为日期类型存储,只不过在数据显示上和存储时的格式一致(存时间戳返回就是时间戳,字符串返回就是字符串,但是推荐存标准化的UTC时间或时间戳,避免类型不一致)。

时区问题

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获取系统时区idTimeZone.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和nested类型的区别,各自的应用场景是什么

object为es的默认对象类型,嵌套的json对象存入es就会被默认设置为object类型。es内部会将嵌套的json对象扁平化转换存储。

例如,一个普通的json

{   "region": "US",  "manager": {     "age":     30,    "name": {       "first": "John",      "last":  "Smith"    }  }}

在es内部会被转换为扁平化的基础json数据

{  "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内部会被转换为:

{  "group" :        "fans",  "user.first" : [ "alice", "john" ],  "user.last" :  [ "smith", "white" ]}

user.first和user.last字段被转换为多值字段,数据之间的关联性就会丢失,导致查询结果有误。

此时用nested类型就可以解决此问题。

查询

term和match匹配有什么区别?

term为精确匹配,查询时不对关键词进行分词。而match用于全文检索,首先会对检索关键词进行分词,然后进行全文搜索。

must,filter,post_filter有什么区别?

must为查询上下文(query context),查询时会计算分值(文档相关性)。filter为过滤上下文,查询时不计算分值。而post_filter为后置过滤器,会对聚合的结果也进行过滤。执行顺序为:filter -> aggregations - post_filter。

query context & filter context区别?

must/should为查询上下文。filter或must_not在参数 bool的查询中/filter在constant_score的查询/filter aggretion这些场景中为过滤上下文。

查询上下文会计算返回文档的分值,而过滤上下文不计算分值,语义只是此文档是否匹配,而不计算相关度。在过滤上下文时,es会自动对过滤器进行缓存从而提高查询性能。

转载地址:http://vbvdm.baihongyu.com/

你可能感兴趣的文章
第八周网络攻防作业
查看>>
页面输出缓存之ASP.Net性能优化篇
查看>>
内网中本机如何开远程桌面,接受其他主机连接到本机
查看>>
分组背包问题
查看>>
本地安装xssing
查看>>
浏览网页常用快捷键
查看>>
mySQL 视图
查看>>
软件包管理 之 用apt+synaptic 在线安装或升级Fedora core 4.0 软件包── 为新手指南...
查看>>
JS面向对象、prototype、call()、apply()
查看>>
初步接触XCode和IPhone Simulator
查看>>
约束满足问题的局部搜索
查看>>
Jquery 遍历数组之grep()方法介绍
查看>>
黑马程序员—12-oc类跟对象
查看>>
Django分页
查看>>
吐槽开发的代码未自测直接给 QA 测试带来的小烦恼 分类: JavaScri...
查看>>
原生选项卡切换
查看>>
C# DataGridView中指定的单元格不能编辑
查看>>
软件架构笔记 二
查看>>
JAVA NIO
查看>>
Win7数据源(ODBC)配置只有SQLSever的驱动的问题
查看>>