一、索引(index)
一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。索引类似于关系型数据库中Database的概念。在一个集群中,如果你想,可以定义任意多的索引。
二、类型(type)
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。类型类似于关系型数据库中Table的概念。
三、文档(document)
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,只要你想,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。文档类似于关系型数据库中Record的概念。实际上一个文档除了用户定义的数据外,还包括_index
、_type
和_id
字段。
四、Mapping详解
Mapping是ES中的一个很重要的内容,它类似于传统关系型数据中table的schema,用于定义一个索引(index)的某个类型(type)的数据的结构。
mapping中主要包括字段名、字段数据类型和字段索引类型这3个方面的定义。
在ES中,字段如果不建立索引,则就不能以这个字段作为查询条件来搜索。也就是说,不建立索引的字段仅仅能起到数据载体的作用。
索引类型 | 解释 |
---|---|
analyzed | 首先分析这个字符串,然后再建立索引。换言之,以全文形式索引此字段。 |
not_analyzed | 索引这个字段,使之可以被搜索,但是索引内容和指定值一样。不分析此字段。 |
no | 不索引这个字段。这个字段不能被搜索到。 |
如果索引类型设置为analyzed,在表示ES会先对这个字段进行分析(一般来说,就是自然语言中的分词),ES内置了不少分析器(analyser)
五、查看集群(Cluster)信息相关API
可用linux 命令curl来发送http请求 curl <-Xaction> url -d 'body'
这里的action表示HTTP协议中的各种动作,包括GET、POST、PUT、DELETE等
(1)查看集群健康信息。
curl -XGET "localhost:9200/_cat/heath?v"
curl -l -k -uuser:password -H 'Content-Type: application/json' 'http://ES_HOST:ES_PORT/_cluster/health?pretty'
返回结果
{
“cluster_name” : “es_9423_6164”,
“status” : “green”,
“timed_out” : false,
“number_of_nodes” : 3,
“number_of_data_nodes” : 3,
“active_primary_shards” : 1,
“active_shards” : 3,
“relocating_shards” : 0,
“initializing_shards” : 0,
“unassigned_shards” : 0,
“delayed_unassigned_shards” : 0,
“number_of_pending_tasks” : 0,
“number_of_in_flight_fetch” : 0,
“task_max_waiting_in_queue_millis” : 0,
“active_shards_percent_as_number” : 100.0
}
我们也可以在请求中添加help参数来查看每个操作返回结果字段的意义curl -XGET "localhost:9200/_cat/heath?help"
(2)查看集群中的节点信息
curl -XGET "localhost:9200/_cat/nodes?v"
(3)查看集群中的索引信息。
curl -XGET "localhost:9200/_cat/indices?v"
六、索引(Index)相关API
(1)创建一个新的索引
curl -XPUT "localhost:9200/index_test"
上面的操作使用默认的配置信息创建一个索引。大多数情况下,我们想在索引创建的时候就将我们所需的mapping和其他配置确定好。下面的操作就可以在创建索引的同时,创建settings和mappingcurl -XPUT "localhost:9200/index_test" -d ' # 注意这里的'号
{
"settings": {
"index": {
"number_of_replicas": "1", # 设置复制数
"number_of_shards": "5" # 设置主分片数
}
},
"mappings": { # 创建mapping
"test_type": { # 在index中创建一个新的type(相当于table)
"properties": {
"name": { # 创建一个字段(string类型数据,使用普通索引)
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}
}'
(2)删除一个索引。
curl -XDELETE "localhost:9200/index_test"
七、映射(Mapping)相关API
6.2 mapping详细说明
{
“type” : “text”, #是数据类型一般文本使用text(可分词进行模糊查询);keyword无法被分词(不需要执行分词器),用于精确查找
“analyzer” : “ik_max_word”, #指定分词器,一般使用最大分词:ik_max_word
“normalizer” : “normalizer_name”, #字段标准化规则;如把所有字符转为小写;具体如下举例
“boost” : 1.5, #字段权重;用于查询时评分,关键字段的权重就会高一些,默认都是1;另外查询时可临时指定权重
“coerce” : true, #清理脏数据:1,字符串会被强制转换为整数 2,浮点数被强制转换为整数;默认为true
“copy_to” : “field_name”, #自定_all字段;指定某几个字段拼接成自定义;具体如下举例
“doc_values” : true, #加快排序、聚合操作,但需要额外存储空间;默认true,对于确定不需要排序和聚合的字段可false
“dynamic” : true, #新字段动态添加 true:无限制 false:数据可写入但该字段不保留 ‘strict’:无法写入抛异常
“enabled” : true, #是否会被索引,但都会存储;可以针对一整个_doc
“fielddata” : false, #针对text字段加快排序和聚合(doc_values对text无效);此项官网建议不开启,非常消耗内存
“eager_global_ordinals”: true, #是否开启全局预加载,加快查询;此参数只支持text和keyword,keyword默认可用,而text需要设置fielddata属性
“format” : “yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis” ,#格式化 此参数代表可接受的时间格式 3种都接受
“ignore_above” : 100, #指定字段索引和存储的长度最大值,超过最大值的会被忽略
“ignore_malformed” : false ,#插入文档时是否忽略类型 默认是false 类型不一致无法插入
“index_options” : “docs” ,
# 4个可选参数
# docs(索引文档号),
# freqs(文档号 + 词频),
# positions(文档号 + 词频 + 位置,通常用来距离查询),
# offsets(文档号 + 词频 + 位置 + 偏移量,通常被使用在高亮字段)
# 分词字段默认是position,其他的默认是docs
“index” : true, #该字段是否会被索引和可查询 默认true
“fields”: {“raw”: {“type”: “keyword”}} ,#可以对一个字段提供多种索引模式,使用text类型做全文检索,也可使用keyword类型做聚合和排序
“norms” : true, #用于标准化文档,以便查询时计算文档的相关性。建议不开启
“null_value” : “NULL”, #可以让值为null的字段显式的可索引、可搜索
“position_increment_gap” : 0 ,#词组查询时可以跨词查询 既可变为分词查询 默认100
“properties” : {}, #嵌套属性,例如该字段是音乐,音乐还有歌词,类型,歌手等属性
“search_analyzer” : “ik_max_word” ,#查询分词器;一般情况和analyzer对应
“similarity” : “BM25”,#用于指定文档评分模型,参数有三个:
# BM25 :ES和Lucene默认的评分模型
# classic :TF/IDF评分
# boolean:布尔模型评分
“store” : true, #默认情况false,其实并不是真没有存储,_source字段里会保存一份原始文档。
# 在某些情况下,store参数有意义,比如一个文档里面有title、date和超大的content字段,如果只想获取title和date
“term_vector” : “no” #默认不存储向量信息,
# 支持参数yes(term存储),
# with_positions(term + 位置),
# with_offsets(term + 偏移量),
# with_positions_offsets(term + 位置 + 偏移量)
# 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用
}
normalizer举例:
{
“settings”: {
“analysis”: {
“normalizer”: {
“my_normalizer”: {
“type”: “custom”,
“char_filter”: [],
“filter”: [“lowercase”, “asciifolding”]
}
}
}
},
“mappings”: {
“type”: {
“properties”: {
“foo”: {
“type”: “keyword”,
“normalizer”: “my_normalizer”
}
}
}
}
}
copy_to举例:
{
“mappings”: {
“my_type”: {
“properties”: {
“first_name”: {
“type”: “text”,
“copy_to”: “full_name”
},
“last_name”: {
“type”: “text”,
“copy_to”: “full_name”
},
“full_name”: {
“type”: “text”
}
}
}
}
}
(1)创建索引的mapping。
curl -XPUT 'localhost:9200/index_test/_mapping/test_type' -d '
{
"test_type": { # 注意,这里的test_type与url上的test_type名保存一致
"properties": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}'
如果不想单独创建mapping,可以使用上一节的方法(创建索引时创建mappings)
ES还给我们准备另外一种创建mapping的方式,
步骤1 创建一个扩展名为test_type.json的文件名,其中type_test就是mapping所对应的type名。
步骤2 在test_type.json中输入mapping信息。假设你的mapping如下:{
"test_type": { # 注意,这里的test_type与json文件名必须一致
"properties": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}
步骤3 在$ES_HOME/config/路径下创建mappings/index_test子目录,这里的index_test目录名必须与我们要建立的索引名一致。将test_type.json文件拷贝到index_tes目录下。
步骤4 创建index_test索引。操作如下:curl -XPUT "localhost:9200/index_test" # 注意,这里的索引名必须与mappings下新建的index_test目录名一致
(2)删除mapping。
curl -XDELETE 'localhost:9200/index_test/_mapping/test_type'
(3)查看索引的mapping。
curl -XGET 'localhost:9200/index_test/_mapping/test_type'
文档(document)相关API
(1)新增一个文档。
curl -XPUT 'localhost:9200/index_test/test_type/1?pretty' -d ' # 这里的pretty参数的作用是使得返回的json显示地更加好看。1是文档的id值(唯一键)。
{
"name": "zhangsan",
"age" : "12"
}'
{
"name": "zhangsan",
"age" : "12"
}'
(2)更新一个文档
curl -XPOST 'localhost:9200/index_test/test_type/1?pretty' -d ' # 这里的1必须是索引中已经存在id,否则就会变成新增文档操作
{
"name": "lisi",
"age" : "12"
}'
(3)删除一个文档
curl -XDELETE 'localhost:9200/index_test/test_type/1?pretty' # 这里的1必须是索引中已经存在id
(4)查询单个文档
curl -XGET 'localhost:9200/index_test/test_type/1?pretty'
(5)普通聚合,类似distinct
curl -XGET -H ‘Content-Type: application/json’ ‘http://user:pwd@10.202.209.111:9200/apk/_search’ -d ‘
{
"size": 0,
"aggs": {
"return_card": {
"cardinality": {
"field": "mfsha1"
}
}
}
}
'
多个值的聚合,采用script,注意script的字段相加要用空格连起来问题
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"sexprof": {
"cardinality": {
"script": {
"source": "doc['uid'].value+' '+doc['cert_md5'].value+' '+doc['version_code'].value"
}
}
}
}
}
求某个字段的count数,类似count group by
{
"size": 0,
"aggs": {
"return_card": {
"terms": {
"field": "sign"
}
}
}
}