网站建设需要的材料,工地找工作哪个软件好,C语言网站开发pdf,做网站地图的步骤主要内容 elasticsearch 中的字符串#xff08;keyword#xff09;类型 的详解和范例 elasticsearch 中的字符串/文本#xff08;text#xff09;类型 的详解和范例 elasticsearch 中的数字#xff08;数值#xff09;类型 的详解和范例 elasticsearch 中的布尔#…主要内容 elasticsearch 中的字符串keyword类型 的详解和范例 elasticsearch 中的字符串/文本text类型 的详解和范例 elasticsearch 中的数字数值类型 的详解和范例 elasticsearch 中的布尔boolean类型 的详解和范例 elasticsearch 中的日期date类型 的详解和范例 elasticsearch 中的地理geo_point、geo_shape类型 的详解和范例 elasticsearch 中的对象类型 的详解和范例 elasticsearch 中的数组类型 的详解和范例
概要
本篇文章主要讲解elasticsearch在业务中经常用到的字段类型通过大量的范例来学习和理解不同字段类型的应用场景。范例elasticsearch使用的版本为7.17.5。
简述
在Elasticsearch的映射关系中每个字段都对应一个数据类型或者字段类型这些类型规范了字段存储的值和用途。例如可以将字符串索引到text和keyword字段。text字段的值用于全文搜索keyword字段的值存储时不会被分词建立索引主要用于统计计算等操作。
内容
字符串keyword类型 详解 keyword类型用于存储结构化的内容 keyword类型是不进行切分的字符串类型 不进行切分 在索引时对keyword类型的数据不进行切分直接构建倒排索引 在搜索时对该类型的查询字符串不进行切分后的部分匹配 keyword类型数据一般用于对文档的过滤、排序和聚合 在现实场景中keyword经常用于描述ID、电子邮件、主机名、邮政编码、标签、姓名、产品类型、用户ID、URL和状态码等 keyword类型数据一般用于比较字符串是否相等不对数据进行部分匹配因此一般查询这种类型的数据时使用term查询
字符串keyword类型 范例
1.创建user索引库并插入一条数据
#建立一个人名索引,设定姓名字段为keyword字段
PUT /user
{mappings: {properties: {user_name: {type: keyword}}}
}#插入数据
PUT /user/_doc/001
{user_name: 张三
}
2.使用term查询刚刚写入的数据
#使用term查询刚刚写入的数据
GET /user/_search
{query: {term: {user_name: {value: 张三}}}
}#返回的结果如下
{took: 0,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 1,relation: eq},max_score: 0.2876821,hits: [{_index: user,_type: _doc,_id: 001,_score: 0.2876821,_source: {user_name: 张三}}]}
}
由搜索结果可以看出,使用term进行全字符串匹配张三可以搜索到命中文档。
3.使用match查询刚刚写入的数据中带有张的记录
#使用match查询刚刚写入的数据中带有张的记录
GET /user/_search
{query: {match: {user_name: 张}}
}#返回的结果如下
{took: 0,timed_out: false,_shards: {total: 1,successful: 1,skipped: 0,failed: 0},hits: {total: {value: 0,relation: eq},max_score: null,hits: []}
}
由搜索结果可以看出对keyword类型使用match搜索进行匹配是不会命中文档的。
字符串/文本text类型 的详解 text类型是可进行切分的字符串类型。 可切分 在索引时可按照相应的切词算法对文本内容进行切分然后构建倒排索引 在搜索时对该类型的查询字符串按照用户的切词算法进行切分然后对切分后的部分匹配打分 text类型用于进行全文搜索也称为全文检索text类型允许用户在每个全文字段中搜索单个单词 在现实场景中text经常用于电子邮箱正文或产品描述的全文等 text不适合进行排序也不适合进行聚合计算。如果字段需要聚合计算或者排序推荐使用keyword类型
字符串/文本text类型 的范例一
1.创建一个hotel索引库并插入一条数据
#建立一个hotel索引,可以设定title字段为text字段
PUT /hotel
{mappings: {properties: {title: {type: text}}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店
}
2.使用term查询刚刚写入的数据
#按照普通的term进行搜索
GET /hotel/_search
{query: {term: {title: {value: 文雅酒店}}}
}#返回的结果如下
{took : 570,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 0,relation : eq},max_score : null,hits : [ ]}
} 根据返回的结果可知,上面的请求并没有搜索到文档。 term搜索用于搜索值和文档对应的字段是否完全相等,而对于text类型的数据在建立索引时ES已经进行了切分并建立了倒排索引因此使用term没有查询到数据。一般情况下搜索text类型的数据时应使用match搜索。
3.使用match查询刚刚写入的数据中带有文雅的记录
#按照普通的match进行搜索
GET /hotel/_search
{query: {match: {title: 文雅}}
}#返回结果如下
{took : 1,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 0.5753642,hits : [{_index : hotel,_type : _doc,_id : 001,_score : 0.5753642,_source : {title : 文雅酒店}}]}
}
字符串/文本text类型 的范例二
1.创建myindex-2_13索引库并插入数据
#创建索引映射并指定tagname字段的字段类型为text类型
PUT myindex-2_13
{mappings: {properties: {tagname: {type: text}}}
}#插入文档数据
PUT myindex-2_13/_doc/1
{tagname:江苏省
}#插入文档数据
PUT myindex-2_13/_doc/2
{tagname:河北省
}
2.根据tagname字段内容分词然后对所有分词进行匹配搜索
#根据tagname字段内容分词然后对所有分词进行匹配搜索
GET myindex-2_13/_doc/_search
{query: {match: {tagname: 河南省}}
}#返回的结果如下
{took : 2,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 2,relation : eq},max_score : 0.8754687,hits : [{_index : myindex-2_13,_type : _doc,_id : 2,_score : 0.8754687,_source : {tagname : 河北省}},{_index : myindex-2_13,_type : _doc,_id : 1,_score : 0.18232156,_source : {tagname : 江苏省}}]}
} 以上搜索结果中把江苏省和河北省这两行数据都返回了这是因为目前默认的分词器把河南省分了河、南、省三个词而河北省和江苏省分别分成河、北、省和江、苏、省这两个词被分词后都有一个省字所以搜索时被全文匹配到了。在实际业务中如果我们要对字段的内容进行全文搜索可以使用text类型如果要聚合查询或者精准匹配则尽量使用keyword类型。
字符串/文本text类型 的范例三 对于大多数想要对文本字段执行更过操作的用户也可以使用多字段映射其中既有text类型可以用于全文检索又有keyword类型可以用于聚合分析语法如下 PUT 索引库名称
{mappings: {properties: {my_field: {type: text,fields: {keyword: {type: keyword}}}}}
} 由以上语句可知my_field字段的映射关系是父字段类型是text类型子字段类型是keyword类型。
1.创建myindex-2_14索引库并插入数据
#创建索引映射
PUT myindex-2_14
{mappings: {properties: {tagname: {type: text,fields: {keyword: {type: keyword}}}}}
}#插入文档数据
PUT myindex-2_14/_doc/1
{tagname:江苏省
}#插入文档数据
PUT myindex-2_14/_doc/2
{tagname:河北省
}
2.根据父字段text类型搜索符合要求的文档数据
#根据父字段text类型搜索符合要求的文档数据
GET myindex-2_14/_doc/_search
{query: {match: {tagname: 河南省}}
}#返回的结果为
{took : 1029,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 2,relation : eq},max_score : 0.8754687,hits : [{_index : myindex-2_14,_type : _doc,_id : 2,_score : 0.8754687,_source : {tagname : 河北省}},{_index : myindex-2_14,_type : _doc,_id : 1,_score : 0.18232156,_source : {tagname : 江苏省}}]}
} 其中使用tagname字段的父字段text类型进行搜索因为父类型是text类型。所以搜索时会进行分词。结果返回了包含河北省和江苏省的文档信息
3.利用tagname字段的子字段keyword类型进行匹配查询
#利用tagname字段的子字段keyword类型进行匹配查询
GET myindex-2_14/_search
{query: {match: {tagname.keyword: 江苏省}}
}#返回结果为
{took : 1,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 0.6931471,hits : [{_index : myindex-2_14,_type : _doc,_id : 1,_score : 0.6931471,_source : {tagname : 江苏省}}]}
} 其中tagname.keyword代表使用了tagname字段的子字段keyword类型进行了不分词搜索需要保证搜索的内容和字段存储的内容完全匹配所以从当前索引库中匹配到了数据。
elasticsearch 中的数字数值类型 的详解 elasticsearch支持的数据类型有long、integer、short、byte、double、float、scaled_float、half_float和unsigned_long等。各类型所表达的数值范围可以参考官方文档网址为Numeric field types | Elasticsearch Guide [8.7] | Elastic。 为节约存储空间并提升搜索和索引的效率在实际应用中在满足需求的情况下应尽可能选择范围小的数据类型。比如年龄字段的取值最大值不会超过200因此选择byte类型即可 数值类型的数据也可用于对进行过滤、排序和聚合 对于数值型数据,一般使用term搜索或者范围搜索
elasticsearch 中的数字数值类型 的范例一
1.更新hotel索引库的mapping,并为hotel索引库定义价格、星级和评论数等字段更新后再插入数据。
#一个酒店搜索项目,酒店的索引除了包含酒店名称和城市之外还需要定义价格、星级和评论数等。
PUT /hotel/_mapping
{properties: {city: {type: keyword},price: {type: double},start: {type: byte},comment_count: {type: integer}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2
}
2.搜索价格为200~300(包含200和300)的酒店
#搜索价格为200~300(包含200和300)的酒店
GET /hotel/_search
{query: {range: {price: {gte: 200,lte: 300}}}
}#返回结果如下
{took : 596,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 1.0,hits : [{_index : hotel,_type : _doc,_id : 001,_score : 1.0,_source : {title : 文雅酒店,city : 上海,price : 270,start : 10,comment_count : 2}}]}
}
elasticsearch 中的数字数值类型 的范例二
1.创建索引并创建字段映射关系
#创建索引并创建字段映射关系
PUT myindex-2_09
{mappings: {properties: {number: {type: integer},time_in_secondes: {type: float},price: {type: scaled_float,scaling_factor: 100}}}
}#插入文档数据
PUT myindex-2_09/_doc/1?refresh
{number:1,time_in_secondes:1.001,price:1.11
} 在以上语句创建的索引映射中scaling_factor参数表示数值在存储时使用了缩放因子该值在存储时乘以缩放因子并四舍五入到最接近long类型的值比如1.11实际存储的数据是111.注意这个参数是必不可少的。 就上面范例中的数字类型而言他们可以存储任何数字但是我们在使用时尽量选择可以满足需求的最小数值类型这样可以更有效地编制索引和进行搜索同时也可以节省一部分的存储空间。
2.精确查询price为1.11的数据
#精确查询price为1.11的数据
GET myindex-2_09/_search
{query: {term: {price: {value: 1.11}}}
}
elasticsearch 中的布尔boolean类型 的详解 布尔字段接受JSON格式的true和false,但也可以接受解释为真或假的字符串,false,false,true,true 布尔类型使用boolean定义用于业务中的二值表示如商品是否售罄房屋是否已租酒店房间是否满房等。
elasticsearch 中的布尔boolean类型 的范例一
1.一个酒店搜索项目,酒店的索引除了包含酒店名称、城市、价格、星级、评论数之外还需要定义是否 满房等。其次插入数据
#一个酒店搜索项目,酒店的索引除了包含酒店名称、城市、价格、星级、评论数之外还需要定义是否
满房等。
PUT /hotel/_mapping
{properties: {full_room: {type: boolean}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2,full_room:true
}
2.查询满房的酒店
#查询满房的酒店
GET hotel/_search
{query: {term: {full_room: {value: true}}}
}#返回结果如下
{took : 0,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 0.2876821,hits : [{_index : hotel,_type : _doc,_id : 001,_score : 0.2876821,_source : {title : 文雅酒店,city : 上海,price : 270,start : 10,comment_count : 2,full_room : true}}]}
}
elasticsearch 中的布尔boolean类型 的范例二
1.创建索引myindex-2_03映射并指定is_published字段类型为布尔类型
#创建索引映射并指定is_published字段类型为布尔类型
PUT myindex-2_03
{mappings: {properties: {is_published: {type: boolean}}}
}#新增数据字段值必须和映射类型匹配
POST myindex-2_03/_doc/1?pretty
{is_published: true
}POST myindex-2_03/_doc/2?pretty
{is_published: true
}
2.查询索引库中is_publish字段的值是true的数据
#查询索引库中is_publish字段的值是true的数据
GET myindex-2_03/_search
{query: {term: {is_published: {value: true}}}
}
#返回结果如下
{took : 0,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 0.6931471,hits : [{_index : myindex-2_03,_type : _doc,_id : 1,_score : 0.6931471,_source : {is_published : true}}]}
}
3.在使用布尔类型字段时需要注意的是布尔类型的查询不能使用0或者1代替否则会抛出异常
#在使用布尔类型字段时需要注意的是布尔类型的查询不能使用0或者1代替否则会抛出异常
POST myindex-2_03/_doc/3?pretty
{is_published: 1
}#返回结果如下
{error : {root_cause : [{type : mapper_parsing_exception,reason : failed to parse field [is_published] of type [boolean] in
document with id 3. Preview of fields value: 1}],type : mapper_parsing_exception,reason : failed to parse field [is_published] of type [boolean] in document
with id 3. Preview of fields value: 1,caused_by : {type : json_parse_exception,reason : Current token (VALUE_NUMBER_INT) not of boolean type\n at [Source:
(ByteArrayInputStream); line: 2, column: 20]}},status : 400
}#可以看到使用1作为筛选值进行查询时不能正确地转换为布尔类型的值。如果需要对布尔值进行转换可以使用
运行时脚本来处理
GET myindex-2_03/_search
{fields: [{field: weight}],runtime_mappings: {weight: {type: long,script: emit(doc[is_published].value?1:0)}}
}
#返回结果如下
{took : 1,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 2,relation : eq},max_score : 1.0,hits : [{_index : myindex-2_03,_type : _doc,_id : 2,_score : 1.0,_source : {is_published : false},fields : {weight : [0]}},{_index : myindex-2_03,_type : _doc,_id : 1,_score : 1.0,_source : {is_published : true},fields : {weight : [1]}}]}
}
elasticsearch 中的日期date类型 的详解 JSON格式规范中没有对日期数据类型进行定义。 elasticsearch一般使用如下形式表示日期类型数据 格式化的日期字符串例如 2015-01-01 或 2015/01/01 12:10:30 毫秒级的长整型(一个表示自纪元以来毫秒数的长整形数字)表示从1970年1月1日0点到现在的毫秒数 秒级别的整形(表示从纪元开始的秒数的整数)表示从1970年1月1日0点到现在的秒数 在Elasticsearch内部日期转换为UTC如果指定了时区并存储为毫秒数时间戳。 日期类型的默认格式为strict_date_optional_time||epoch_millis。其中strict_date_optional_time的含义是严格的时间类型支持yyyy-MM-dd、yyyyMMdd、yyyyMMddHHmmss、yyyy-MM-ddTHH:mm:ss、yyyy-MM-ddTHH:mm:ss.SSS和yyyy-MM-ddTHH:mm:ss:SSSZ等格式epoch_millis的含义是从1970年1月1日0点到现在的毫秒数。 Elasticsearch中的日期类型可以时包含日期格式的字符串例如2021-01-01或2021/01/01 12:10:30等格式也可以使用自纪元以来的毫秒数来表示注在Unix中纪元是指UTC时间1970年1月1日00:00:00。 对日期的查询在内部转换为范围查询聚合和存储字段的结果将根据与字段关联的日期格式转换回字符串。 日期类型默认不支持yyyy-MM-dd HH:mm:ss格式,如果经常使用这种格式,可以在索引的mapping中设置日期字段的 format属性为自定义格式。 搜索日期数据时一般使用范围查询。
elasticsearch 中的日期date类型 的范例一
1.一个酒店搜索项目,酒店的索引除了包含酒店名称、城市、价格、星级、评论数、是否满房之外还需要定义日期等。
#一个酒店搜索项目,酒店的索引除了包含酒店名称、城市、价格、星级、评论数、是否满房之外还需要定义日期等。
PUT /hotel/_mapping
{properties: {create_time: {type: date}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2,full_room:true,create_time:20210115
}
2.搜索创建日期为2015年的酒店
#搜索创建日期为2015年的酒店
GET hotel/_search
{query: {range: {create_time: {gte: 20150101,lt: 20220112}}}
}#返回结果如下
{took : 14,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 1.0,hits : [{_index : hotel,_type : _doc,_id : 001,_score : 1.0,_source : {title : 文雅酒店,city : 上海,price : 270,start : 10,comment_count : 2,full_room : true,create_time : 20210115}}]}
}
3.删除原来的hotel索引库构建新的hotel索引库并设置create_time字段的格式为yyyy-MM-dd HH:mm:ss
#设置create_time字段的格式为yyyy-MM-dd HH:mm:ss
PUT /hotel
{mappings: {properties: {title: {type: text},city: {type: keyword},price: {type: double},start: {type: byte},comment_count: {type: integer},full_room: {type: boolean},create_time: {type: date,format: yyyy-MM-dd HH:mm:ss}}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2,full_room:true,create_time:20210115
}#返回结果如下
{error : {root_cause : [{type : mapper_parsing_exception,reason : failed to parse field [create_time] of type [date] in document
with id 001. Preview of fields value: 20210115}],type : mapper_parsing_exception,reason : failed to parse field [create_time] of type [date] in document
with id 001. Preview of fields value: 20210115,caused_by : {type : illegal_argument_exception,reason : failed to parse date field [20210115] with format [yyyy-MM-dd
HH:mm:ss],caused_by : {type : date_time_parse_exception,reason : Text 20210115 could not be parsed at index 0}}},status : 400
} 根据错误信息可知错误的原因是写入的数据格式和定义的数据格式不同
3.插入create_time的格式为yyyy-MM-dd HH:mm:ss数据
#插入create_time的格式为yyyy-MM-dd HH:mm:ss数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2,full_room:true,create_time:2021-01-15 01:23:30
}
elasticsearch 中的日期date类型 的范例二
#创建索引映射并指定date字段的字段类型为日期类型
PUT myindex-2_04
{mappings: {properties: {date:{type: date}}}
}#插入文档数据
PUT myindex-2_04/_doc/1
{date:2015-01-01
}#插入文档数据
PUT myindex-2_04/_doc/2
{date: 2015-01-01T12:10:30Z
}#插入文档数据
PUT myindex-2_04/_doc/3
{date:1420070400001
}
#以上3种不同格式的日期数据都被插入到索引库中。#创建索引并为日期类型的字段指定具体的日期格式
PUT myindex-2_05
{mappings: {properties: {date: {type: date,format: yyyy-MM-dd HH:mm:ss}}}
}
#以下语句插入文档数据时将会抛出异常因为日期内容不符合映射格式
PUT myindex-2_05/_doc/1
{date:2015-01-01
}#以下语句插入文档数据时将会抛出异常因为日期内容不符合映射格式
PUT myindex-2_05/_doc/2
{date:2015-01-01T12:10:30Z
}#以下语句插入文档数据时将会抛出异常因为日期内容不符合映射格式
PUT myindex-2_05/_doc/3
{date:1420070400001
}
#以下语句文档数据正常插入,因为日期内容符合字段指定的日期格式
PUT myindex-2_05/_doc/4
{date:2015-01-01 12:02:56
}
elasticsearch 中的地理geo_point、geo_shape类型 的详解 地理位置geo是用于存储经纬度的字段类型。 用例场景如下 在边界框内、中心点的特定距离内或多边形内查找地理点 按地理位置或距中心点的距离聚合文档 将距离整合到文档的相关性得分中 按距离对文档排序 在生活中我们可能会遇到根据当前所在的位置找到离自己最近的符合条件的一些商店、酒店之类的情况。在elasticsearch中也支持这种业务的查询它主要支持两种类型的地理查询一种是地理点geo_point查询即经纬度查询另一种是地理形状geo_shape查询支持点、线、圈、多边形查询等。
geo_shape geo_shape空间位置类型支持地理形状的搜索即点、线、圈、多边形搜索等。比如我们想要找到最接近给定位置的路线就可以使用此类型。语法如下
PUT /索引库名称
{mappings: {properties: {location: {type: geo_shape}}}
}
geo_point 在移动互联网时代用户借助移动设备产生的消费越来越多。例如用户要根据某个地理位置来搜索酒店此时可以把酒店的经纬度数据设置为地理数据类型。该类型的定义需要在mapping中指定目标字段的数据类型为geo_point类型 elasticseach也提供了地理点查询的类型即geo_point类型。使用语法如下
PUT 索引库名称
{mappings: {properties: {location: {type: geo_point}}}
}
elasticsearch 中的地理geo_point类型 范例
#一个酒店搜索项目,酒店的索引除了包含酒店名称、城市、价格、星级、评论数、是否满房、日期之外还需要定义位
置等。
PUT /hotel/_mapping
{properties: {location: {type: geo_point}}
}#插入数据
POST /hotel/_doc/001
{title:文雅酒店,city:上海,price:270,start:10,comment_count:2,full_room:true,create_time:2021-01-15 01:23:30,location:{lat:40.012134,lon:116.497553}
}#搜索指定的两个地理位置形成的矩形范围中包含的酒店信息
GET hotel/_search
{query: {bool: {must: [{match_all: {}}],filter: {geo_bounding_box: {location: {top_left: {lat: 40.73,lon: -74.1},bottom_right: {lat: 40.01,lon: -71.12}}}}}}
}#搜索指定的多个地理位置形成的多边形范围中包含酒店信息
GET /hotel/_search
{query: {bool: {must: [{match_all: {}}],filter: {geo_polygon: {location: {points: [{lat: 40.73,lon: -74.1},{lat: 40.83,lon: -75.1},{lat: 40.93,lon: -76.1}]}}}}}
}#搜索指定位置1000km范围内的酒店数据
GET /hotel/_search
{query: {bool: {must: [{match_all: {}}],filter:{geo_distance: {distance: 1000km,location: {lat: 40.73,lon: -74.1}}}}}
}#搜索距离指定位置一定范围内有多少个酒店
GET /hotel/_search
{size: 0,aggs: {count_by_distinct: {geo_distance: {field: location,origin: {lat: 52.376,lon: 4.894},ranges: [{from: 100,to: 300}],unit: mi,distance_type: arc}}}
}
elasticsearch 中的地理geo_shape类型 范例
1.创建索引映射并指定location字段的字段类型为geo_shape类型
#创建索引映射并指定location字段的字段类型为geo_shape类型
PUT myindex-geo_shape
{mappings: {properties: {location: {type: geo_shape}}}
}#插入地点相关信息
POST /myindex-geo_shape/_doc?refresh
{name: Wind Wetter,Berlin,Germany,location: {type: point,coordinates: [13.400544,52.530286]}
}
2.搜索指定的两个位置范围内的地点
#搜索指定的两个位置范围内的地点
GET /myindex-geo_shape/_search
{query: {bool: {must: [{match_all: {}}],filter: {geo_shape: {location: {shape: {type: envelope,coordinates: [[13,53],[14,52]]},relation: within}}}}}
}#返回的结果
{took : 3,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 1,relation : eq},max_score : 1.0,hits : [{_index : myindex-geo_shape,_type : _doc,_id : oKSWWYcB7w4YX5_iGU4l,_score : 1.0,_source : {name : Wind Wetter,Berlin,Germany,location : {type : point,coordinates : [13.400544,52.530286]}}}]}
} 由以上语句可知根据需求返回了两个地理位置范围内符合条件的地点。
elasticsearch 中的对象类型 的详解 elasticsearch中的object类型实际就是JSON数据格式 在实际业务中一个文档需要包含其他内部对象。例如在酒店搜索需求中用户希望酒店信息中包含评论数据。评论数据分为好评数量和差评数量。为了支持这种业务在ES中可以使用对象类型。 对象类型和数组类型一样对象类型也不用事先定义在写入文档的时候ES会自动识别并转换为对象类型。
elasticsearch 中的对象类型 的范例一
#向hotel中添加一条数据
PUT /hotel/_doc/002
{title: 好再来酒店,city: 青岛,price: 578.23,comment_info: {properties: {favourable_comment: 199,negative_comment: 68}}
}
#执行以上DSL后,索引hotel增加了一个字段comment_info,它有两个属性,分别是favourable_comment
和negative_comment,二者的类型都是long。#查看hotel的mapping
GET /hotel/_mapping
#hotel 的mapping 响应结果为
{hotel : {mappings : {properties : {city : {type : keyword},comment_count : {type : integer},comment_info : {properties : {properties : {properties : {favourable_comment : {type : long},negative_comment : {type : long}}}}},create_time : {type : date,format : yyyy-MM-dd HH:mm:ss},full_room : {type : boolean},location : {type : geo_point},price : {type : double},start : {type : byte},title : {type : text}}}}
}
#根据对象类型的属性进行搜索,可以直接用.操作符进行指向。
#例如搜索hotel索引中好评数大于200的文档
GET /hotel/_search
{query: {range: {comment_info.properties.favourable_comment: {gte: 36}}}
}
#当然,对象内部还可以包含对象
#评论信息字段comment_info可以增加前3条好评数据
POST /hotel/_doc/002
{title: 好再来酒店,city: 青岛,price: 578.23,comment_info: {properties: {favourable_comment: 199,negative_comment: 68,top3_favourable_comment: {top1: {content: 干净整洁的一家酒店,score:87},top2: {content: 服务周到,停车方便,score:89},top3: {content: 闹中取静,环境优美,score:90}}}}
}
elasticsearch 中的对象类型 的范例二
#创建索引映射
PUT myindex-object
{mappings: {properties: {region: {type: keyword},manager: {properties: {age: {type: integer},name: {properties: {first: {type: text},last: {type: text}}}}}}}
}#对于_id等于1的文档而言manager是一个对象,该对象中又包含一个name对象而name对象中有两个键值对。如果需
要向这个索引映射中插入文档可以使用下面任何一种方式写入#范例一使用嵌套的JSON数据格式进行写入
#使用嵌套的JSON数据格式进行写入
PUT myindex-object/_doc/1
{region:China,manager:{age:30,name:{first:clay,last:zhagng}}
}#范例二使用简单的JSON数据格式进行写入
#使用简单的JSON数据格式进行写入
PUT myindex-object/_doc/2
{region: US,manager.age: 30,manager.name.first: John,manager.name.last: Smith
}#使用以上两种方式写入数据不会影响数据的存储但是会影响查询返回的结果。
#查询数据
GET myindex-object/_doc/_search#返回的结果为
{took : 1,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 2,relation : eq},max_score : 1.0,hits : [{_index : myindex-object,_type : _doc,_id : 1,_score : 1.0,_source : {region : China,manager : {age : 30,name : {first : clay,last : zhagng}}}},{_index : myindex-object,_type : _doc,_id : 2,_score : 1.0,_source : {region : US,manager.age : 30,manager.name.first : John,manager.name.last : Smith}}]}
}
#以上返回信息的写入格式与查询返回的格式一致。
elasticsearch 中的数组类型 的详解 ES数组没有定义方式其使用方式是开箱即用的即无须事先声明在写入时把数据用中括号[]括起来由ES对该字段完成定义。当然如果事先已经定义了字段类型在写数据时以数组形式写入ES也会将该类型转为数组。
elasticsearch 中的数组类型 的范例
#为hotel索引增加一个标签字段名称为tag
PUT /hotel/_mapping
{properties: {tag: {type: keyword}}
}
#查看一下索引hotel的mapping
GET /hotel/_mapping
#返回的结果如下
{hotel : {mappings : {properties : {city : {type : keyword},comment_count : {type : integer},comment_info : {properties : {properties : {properties : {favourable_comment : {type : long},negative_comment : {type : long},top3_favourable_comment : {properties : {top1 : {properties : {content : {type : text,fields : {keyword : {type : keyword,ignore_above : 256}}},score : {type : long}}},top2 : {properties : {content : {type : text,fields : {keyword : {type : keyword,ignore_above : 256}}},score : {type : long}}},top3 : {properties : {content : {type : text,fields : {keyword : {type : keyword,ignore_above : 256}}},score : {type : long}}}}}}}}},create_time : {type : date,format : yyyy-MM-dd HH:mm:ss},full_room : {type : boolean},location : {type : geo_point},price : {type : double},start : {type : byte},tag : {type : keyword},title : {type : text}}}}
}
#通过返回的mapping信息来看新增的tag字段与普通的keyword类型字段没什么区别现在写入一条数据
PUT /hotel/_doc/004
{title:好再来酒店,city:青岛,price:578.23,tags:[有车位,免费WIFI]
}#查询一下写入的数据
GET /hotel/_search#返回的数据为
{took : 0,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 3,relation : eq},max_score : 1.0,hits : [{_index : hotel,_type : _doc,_id : 001,_score : 1.0,_source : {title : 文雅酒店,city : 上海,price : 270,start : 10,comment_count : 2,full_room : true,create_time : 2021-01-15 01:23:30,location : {lat : 40.012134,lon : 116.497553}}},{_index : hotel,_type : _doc,_id : 002,_score : 1.0,_source : {title : 好再来酒店,city : 青岛,price : 578.23,comment_info : {properties : {favourable_comment : 199,negative_comment : 68,top3_favourable_comment : {top1 : {content : 干净整洁的一家酒店,score : 87},top2 : {content : 服务周到,停车方便,score : 89},top3 : {content : 闹中取静,环境优美,score : 90}}}}}},{_index : hotel,_type : _doc,_id : 004,_score : 1.0,_source : {title : 好再来酒店,city : 青岛,price : 578.23,tags : [有车位,免费WIFI]}}]}
}
#通过以上信息可以看到写入的数据的tag字段已经是数组类型了。那么数组类型的数据如何搜索呢
#数组类型的字段适用于元素类型的搜索方式也就是说数组元素适用于什么搜索数组字段就适用于什么搜索。
#在上面的示例中数组元素类型是keyword,该类型可以适用于term搜索则tag字段也可以适用于term搜索
GET /hotel/_search
{query: {term: {tags: {value: 有车位}}}
}#ES中的空数组可以作为missing field,即没有值的字段下面的DSL将插入一条tag为空的数组
POST /hotel/_doc/003
{title:环球酒店,city:青岛,price:530.00,tags:[]
}