结构化索引

前面我们创建的索引以及插入数据,都是由Elasticsearch进行自动判断类型,有些时候我们是需要进行明确字段类型的。

Elasticsearch中支持的数据类型和JSON中数据类型对应关系如下(粗体为默认类型):

JSON类型

ES中数据类型

String

string , text , keyword

Whole number

byte , short , integer , long

Floating point

float , double

Boolean

boolean

Date

date

string类型 在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代。
text 类型 当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。
keyword类型 适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到

创建结构化索引(明确字段及类型)

接口:PUT http://192.168.12.10:9200/myindex
参数:

{
"settings": {
"index": {
"number_of_shards": "2",

"number_of_replicas": "0"
}
},
"mappings": {
"person": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"mail": {
"type": "keyword"
},
"hobby": {
"type": "text"
}
}
}
}
}

结构化查询

首先批量初始化如下数据:

{"index":{"_index":"myindex","_type":"person"}}
{"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球、乒乓球、足球"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球、乒乓球、足球、篮球"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球、篮球、游泳、听音乐"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步、游泳"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐、看电影"}
term查询

主要用于精确匹配字段查询,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)
查询参数格式如下:

{ "term": { "age":   26      }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}

示例参数:

{
"query" : {
"term" : {
"age" : 20
}
}
}
terms查询

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配
示例参数:

{
"query" : {
"terms" : {
"age" : [20,21]
}
}
}
range查询

range 过滤允许我们按照指定范围查找数据
示例参数(查询年龄20~30岁之间的):

{
"query":
{
"range": {
"age": {
"gt":20,
"lt":30
}
}
}
}

gt :: 大于
gte :: 大于等于
lt :: 小于
lte :: 小于等于

exists 查询

exists 查询可以用于查找文档中是否包含指定字段或没有某个字段的数据,类似于SQL语句中的 IS_NULL 条件
示例参数,查询包含card字段的数据:

{
"query": {
"exists": {
"field": "card"
}
}
}
match查询

match 查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。
如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析 match 一下查询字符。
如果 match下指定了一个确切值(在遇到数字,日期,布尔值或者 not_analyzed 的字符串时),它将搜索你给定的值。
参数格式:

{ "match": { "age":   26      }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}

示例参数(查询age=20的数据):

{
"query" : {
"match" : {
"age" : 20
}
}
}
bool查询

bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:
must 多个查询条件的完全匹配,相当于 and 。
must_not 多个查询条件的相反匹配,相当于 not 。
should 至少有一个查询条件匹配, 相当于 or 。
示例参数查询 年龄=21 且 (name =李四 或 age=23 )的数据:

{
"query": {
"bool": {
"must":{ "term": { "age": 21 }},
"should": [
{ "term": { "age": 23}},
{ "term": { "name":"李四"}}
]
}
}
}
过滤查询

上述结构化查询都支持过滤查询嵌套
示例参数(查询年龄为20岁的用户)

{
"query": {
"bool": {
"filter": {
"term": {
"age": 20
}
}
}
}
}

查询和过滤的对比
一条过滤语句会询问每个文档的字段值是否包含着特定值。
查询语句会询问每个文档的字段值与特定值的匹配程度如何。

一条查询语句会计算每个文档与查询语句的相关性(会给出一个相关性评分 _score),并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于全文本搜索。

查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。因此建议,做精确匹配搜索时,最好用过滤语句,因为过滤语句可以缓存数据。