欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

结构化索引及结构化查询

程序员文章站 2022-07-06 19:58:31
...

结构化索引

前面我们创建的索引以及插入数据,都是由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": "[email protected]","hobby":"羽毛球、乒乓球、足球"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"李四","age": 21,"mail": "[email protected]","hobby":"羽毛球、乒乓球、足球、篮球"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"王五","age": 22,"mail": "[email protected]","hobby":"羽毛球、篮球、游泳、听音乐"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"赵六","age": 23,"mail": "[email protected]","hobby":"跑步、游泳"}
{"index":{"_index":"myindex","_type":"person"}}
{"name":"孙七","age": 24,"mail": "[email protected]","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),并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于全文本搜索。

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