为了节省内存的使用,es提供了另一项机制(fielddata_frequency_filter),允许只加载那些词根频率在指定范围(最大,小值)直接的词根与文档的映射关系,最大最小值可以指定为绝对值,例如数字,也可以基于百分比(百分比的计算是基于整个分段(segment),其频率分母不是分段(segment)中所有的文档,而是segment中该字段有值的文档)。可以通过min_segment_size参数来指定分段中必须包含的最小文档数量来排除小段,也就是说可以控制fielddata_frequency_filter的作用范围是包含大于min_segment_size的文档数量的段。fielddata_frequency_filter的使用示例如下:
- format
在JSON文档中,日期表示为字符串。Elasticsearch使用一组预先配置的格式来识别和解析这些字符串,并将其解析为long类型的数值(毫秒)。
日期格式主要包括如下3种方式:
1)自定义格式
2)date mesh(已在DSL查询API中详解)
3)内置格式
1、自定义格式
首先可以使用java定义时间的格式,例如:
PUT my_index
{
“mappings”: {
“_doc”: {
“properties”: {
“date”: {
“type”: “date”,
“format”: “yyyy-MM-dd HH:mm:ss”
}
}
}
}
}
2、date mesh
某些API支持,已在DSL查询API中详细介绍过,这里不再重复。
3、内置格式
elasticsearch为我们内置了大量的格式,如下:
- epoch_millis
时间戳,单位,毫秒。
- epoch_second
时间戳,单位,秒。
- date_optional_time
日期必填,时间可选,其支持的格式如下:
- basic_date
其格式表达式为 :yyyyMMdd
- basic_date_time
其格式表达式为:yyyyMMdd’T’HHmmss.SSSZ
- basic_date_time_no_millis
其格式表达式为:yyyyMMdd’T’HHmmssZ
- basic_ordinal_date
4位数的年 + 3位(day of year),其格式字符串为yyyyDDD
- basic_ordinal_date_time
其格式字符串为yyyyDDD’T’HHmmss.SSSZ
- basic_ordinal_date_time_no_millis
其格式字符串为yyyyDDD’T’HHmmssZ
- basic_time
其格式字符串为HHmmss.SSSZ
- basic_time_no_millis
其格式字符串为HHmmssZ
- basic_t_time
其格式字符串为’T’HHmmss.SSSZ
- basic_t_time_no_millis
其格式字符串为’T’HHmmssZ
- basic_week_date
其格式字符串为xxxx’W’wwe,4为年 ,然后用’W’, 2位week of year(所在年里周序号) 1位 day of week。
- basic_week_date_time
其格式字符串为xxxx’W’wwe’T’HH:mm:ss.SSSZ.
- basic_week_date_time_no_millis
其格式字符串为xxxx’W’wwe’T’HH:mm:ssZ.
- date
其格式字符串为yyyy-MM-dd
- date_hour
其格式字符串为yyyy-MM-dd’T’HH
- date_hour_minute
其格式字符串为yyyy-MM-dd’T’HH:mm
- date_hour_minute_second
其格式字符串为yyyy-MM-dd’T’HH:mm:ss
- date_hour_minute_second_fraction
其格式字符串为yyyy-MM-dd’T’HH:mm:ss.SSS
- date_hour_minute_second_millis
其格式字符串为yyyy-MM-dd’T’HH:mm:ss.SSS
- date_time
其格式字符串为yyyy-MM-dd’T’HH:mm:ss.SSS
- date_time_no_millis
其格式字符串为yyyy-MM-dd’T’HH:mm:ss
- hour
其格式字符串为HH
- hour_minute
其格式字符串为HH:mm
- hour_minute_second
其格式字符串为HH:mm:ss
- hour_minute_second_fraction
其格式字符串为HH:mm:ss.SSS
- hour_minute_second_millis
其格式字符串为HH:mm:ss.SSS
- ordinal_date
其格式字符串为yyyy-DDD,其中DDD为 day of year。
- ordinal_date_time
其格式字符串为yyyy-DDD‘T’HH:mm:ss.SSSZZ,其中DDD为 day of year。
- ordinal_date_time_no_millis
其格式字符串为yyyy-DDD‘T’HH:mm:ssZZ
- time
其格式字符串为HH:mm:ss.SSSZZ
- time_no_millis
其格式字符串为HH:mm:ssZZ
- t_time
其格式字符串为’T’HH:mm:ss.SSSZZ
- t_time_no_millis
其格式字符串为’T’HH:mm:ssZZ
- week_date
其格式字符串为xxxx-'W’ww-e,4位年份,ww表示week of year,e表示day of week。
- week_date_time
其格式字符串为xxxx-'W’ww-e’T’HH:mm:ss.SSSZZ
- week_date_time_no_millis
其格式字符串为xxxx-'W’ww-e’T’HH:mm:ssZZ
- weekyear
其格式字符串为xxxx
- weekyear_week
其格式字符串为xxxx-'W’ww,其中ww为week of year。
- weekyear_week_day
其格式字符串为xxxx-'W’ww-e,其中ww为week of year,e为day of week。
- year
其格式字符串为yyyy
- year_month
其格式字符串为yyyy-MM
- year_month_day
其格式字符串为yyyy-MM-dd
温馨提示,日期格式时,es建议在上述格式之前加上strict_前缀。
- ignore_above
超过ignore_above设置的字符串不会被索引或存储。对于字符串数组,将分别对每个数组元素应ignore_above,超过ignore_above的字符串元素将不会被索引或存储。目前测试的结果为:对于字符串字符长度超过ignore_above会存储,但不索引(也就是无法根据该值去查询)。其测试效果如下:
public static void create_mapping_ignore_above() { // 创建映射
RestHighLevelClient client = EsClient.getClient();
try {
CreateIndexRequest request = new CreateIndexRequest(“mapping_test_ignore_above2”);
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject(“properties”)
.startObject(“lies”)
.field(“type”, “keyword”) // 创建关键字段
.field(“ignore_above”, 10) // 设置长度不能超过10
.endObject()
.endObject()
.endObject();
// request.mapping(“user”, mapping_user);
request.mapping(“_doc”, mapping);
System.out.println(client.indices().create(request, RequestOptions.DEFAULT));
} catch (Throwable e) {
e.printStackTrace();
} finally {
EsClient.close(client);
}
}
public static void index_mapping_ignore_above() { // 索引数据
RestHighLevelClient client = EsClient.getClient();
try {
IndexRequest request = new IndexRequest(“mapping_test_ignore_above2”, “_doc”);
Map<String, Object> data = new HashMap<>();
data.put(“lies”, new String[] {“dingabcdwei”,“huangsw”,“wuyanfengamdule”});
request.source(data);
System.out.println(client.index(request, RequestOptions.DEFAULT));
} catch (Throwable e) {
e.printStackTrace();
} finally {
EsClient.close(client);
}
}
public static void search_ignore_above() { // 查询数据
RestHighLevelClient client = EsClient.getClient();
try {
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(“mapping_test_ignore_above2”);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(
// QueryBuilders.matchAllQuery() // @1
// QueryBuilders.termQuery(“lies”, “dingabcdwei”) // @2
// QueryBuilders.termQuery(“lies”, “huangsw”) // @3
);
searchRequest.source(sourceBuilder);
SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(result);
} catch (Throwable e) {
e.printStackTrace();
} finally {
EsClient.close(client);
}
}
代码@1:首先查询所有数据,其_souce字段的值为:“_source”:{“lies”:[“dingabcdwei”,“huangsw”,“wuyanfengamdule”]},表名不管字符串的值是否大于ignore_above指定的值,都会存储。
代码@2:用超过ignore_above长度的值尝试去搜索,发现无法匹配到记录,表明并未加入到倒排索引中。
代码@3:用未超过ignore_above长度的值尝试去搜索,发现能匹配到记录。
注意:在es中,ignore_above的长度是字符的长度,而es其底层实现lucene是使用字节进行计算的,故,如果要反馈到lucnce,请注意关系。
- ignore_malformed
试图将错误的数据类型索引到字段中,默认情况下会抛出异常,并拒绝整个文档。ignore_malformed参数,如果设置为真,允许错误被忽略。格式不正确的字段不建立索引,但是文档中的其他字 段正常处理。可以创建索引时,设置index.mapping.ignore_malformed 配置项来定义索引级别的默认值,其优先级为 字段级、索引级。
- index
定义字段是否索引,true:代表索引,false表示不索引(则无法通过该字段进行查询),默认值为true。
- index_options
控制文档添加到反向索引的额外内容,其可选择值如下:
-
docs:文档编号添加到倒排索引。
-
freqs:文档编号与访问频率。
-
positions:文档编号、访问频率、词位置(顺序性),proximity 和phrase queries 需要用到该模式。
-
offsets:文档编号,词频率,词偏移量(开始和结束位置)和词位置(序号),高亮显示,需要设置为该模式。
默认情况下,被分析的字符串(analyzed string)字段使用positions,其他字段使用docs;
- fields
fields允许对同一索引中同名的字段进行不同的设置,举例说明:
PUT my_index
{
“mappings”: {
“_doc”: {
“properties”: {
“city”: {
“type”: “text”, // @1
“fields”: { // @2
“raw”: {
“type”: “keyword” // @3
}
}
}
}
}
}
}
@1:上述映射为city字段,定义类型为text,使用全文索引。
@2:为city定义多字段,city.raw,其类型用keyword。
主要就可以用user进行全文匹配,也可以用user.raw进行聚合、排序等操作。另外一种比较常用的场合是对该字段使用不同的分词器。
- norms
字段的评分规范,存储该规范信息,会提高查询时的评分计算效率。虽然规范对计分很有用,但它也需要大量磁盘(通常是索引中每个字段的每个文档一个字节的顺序,甚至对于没有这个特定字段的文档也是如此)。从这里也可以看出,norms适合为过滤或聚合的字段。
注意,可以通过put mapping api 将norms=true更新为norms=false,但无法从false更新到true。
- null_value
将显示的null值替换为新定义的额值。用如下示例做一个说明:
PUT my_index
{
“mappings”: {
“_doc”: {
“properties”: {
“status_code”: {
“type”: “keyword”,
“null_value”: “NULL” // @1
}
}
}
}
}
PUT my_index/_doc/1
{
“status_code”: null // @2
}
PUT my_index/_doc/2
{
“status_code”: [] // @3
}
GET my_index/_search
{
“query”: {
“term”: {
“status_code”: “NULL” // @4
}
}
}
代码@1:为status_code字段定义“NULL”为空值null;
代码@2:该处,存储在status_code为 null_value中定义的值,即"NULL"
代码@3:空数组不包含显式null,因此不会被null_value替换。
代码@4:该处查询,会查询出文档1。其查询结果如下:
{
“took”:4,
“timed_out”:false,
“_shards”:{
“total”:5,
“successful”:5,
“skipped”:0,
“failed”:0
},
“hits”:{
“total”:1,
“max_score”:0.2876821,
“hits”:[
{
“_index”:“mapping_test_null_value”,
“_type”:“_doc”,
“_id”:“RyjGEmcB-TTORxhqI2Zn”,
“_score”:0.2876821,
“_source”:{
“status_code”:null
}
}
]
}
}
null_value具有如下两个特点:
null_value需要与字段的数据类型相同。例如,一个long类型的字段不能有字符串null_value。
null_value只会索引中的值(倒排索引),无法改变_souce字段的值。
- position_increment_gap