elasticsearch基本概念

本文介绍了Elasticsearch的基本概念,包括数据结构、集群、节点、分片与副本的详细解释,以及倒排索引的工作原理。此外,还涵盖了关键属性、字段说明,如查询返回字段、创建和更新文档的操作,以及条件查询的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数据结构

es是文档型的存储方式,一条数据就是一个文档,对于用户来说就是一条JSON.
一个索引下面,有多个文档,一个文档里面有多个字段(灵活的,非结构化的,
也就是每个文档的字段都可以不一样)。

二、集群(Cluster)/节点(Node)/分片(Shards)/副本(Replicasedit)

集群:

	实际上就是多个es实例,启动后,只要cluster.name是相同的,
	相互之间网络关系也是通的,就是一个es集群。

节点:

	实际上就是一个es实例,es的数据存储和搜索等功能都是通过这些具体的实例来实现的。

分片;
	
	一个索引(index)里面的数据可能比较多,不适合单节点存储,索引设置分片,
	不同的分片落在不同的节点上。实际上就是对索引数据的水平拆分,
	分布方式以及如何将其文档聚合回搜索请求的机制完全由 Elasticsearch 管理,
	对用户而言是透明的。

副本:
	
	一个分片可以分为0-N个副本,不同的副本落在不同的节点上,
	写入数据是从分片的主副本写入,然后同步到不同的节点的分片的从副本上,
	所有的副本都可以进行查询。

小结:
	
	一个es实例,会存在某些index(索引,相当于mysql的库)里面的文档数据过多,
	造成单机瓶颈,因为es实例除了维护文档数据,还需要维护倒排索引等信息,
	单机数据量过多会造成磁盘空间不够和搜索效率下降等问题。

	所以引入了集群,多个es实例的cluster.name是相同的,就组成了一个集群。

	一个集群内部,同一个index(索引,只是一个逻辑上的概念)数据,可以通过分片
	将数据散落在不同的节点(物理节点,服务器)。就相当于对index里面的数据进行水平
	拆分。

	但是单个分片数据,有可能又有单点故障的问题,所以每个分片可以设置多个副本,散落在
	不同的节点上。
	
	类似于关系型数据库:数据库集群,假如有个用户表,我担心数据量过大,
	我新建了多个用户表(即 Shard),将用户信息数据切分成多份,
	然后根据某种规则分到这些用户表中,我又担心某个表会出现异常造成数据丢失,
	我又将每个表分别备份了一次(即 Replica )。

三、倒排索引

实际上就是通过对文本的分词,生成这种形式的索引: 分词——>所有包含此分词的文档id/词频(Term出现的次数)/偏移量(offset)数组
倒排索引具体的样式:

在这里插入图片描述
1、Term(单词)

	文本通过分词器分析之后,形成的多个单词

2、Term Dictionary(单词字典):

	顾名思义,它里面维护的是Term,可以理解为Term的集合

3、Term Index(单词索引):

为了更快的找到某个单词,为单词建立索引

4、Posting List(倒排列表):

可以想成py里面的字典,单词就是key,  value是一个数组,
这个数组里面是一系列的元组(文档id、词频(Term出现的次数)、偏移量(offset))

5、倒排索引的寻址过程

分词之后,会根据分出来的词生成一个term index(分词索引),查找的时候,
会先根据这个term index去找到Term Dictionary(分词字典)中的term,
再根据term找到对应的Posting List(倒排列表)

四、关键属性、字段说明

1、查询返回字段说明:

{
  "took": 1,  //整个搜索请求花费多少毫秒
  "timed_out": false,
  "_shards": { //指示搜索了多少分片,以及搜索成功和失败的分片的计数
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": { //用来实际搜索结果集
    "total": 1, // 搜索返回条数
    "max_score": 0.83355963, //搜索结果匹配度
    "hits": [ //查询完整的数据  以_score降序排序
      {
        "_index": "test", //索引
        "_type": "test", //类型
        "_id": "xtoffH0BS_BXL2CbFNQ_", //索引数据id
        "_score": 0.83355963, // 衡量文档与查询的匹配程度
        "_source": { // 结果原数据
          "name": "新浪军事22"
        }
      }
    ]
  }
}

2、创建索引

# 指定mapping创建方式
PUT translated_documents
{
  "mappings": {
		"translated_documents": { # 7版本之前指的是 类型type,7版本之后可以用_doc替换
			"properties": {
				"documentId": {
					"type": "keyword" # keyword 不参与分词
				},
				"translation": {
					"type": "text", # keyword 参与分词,不能用于排序使用,如何想用于排序需要另外设置keyword字段
					"analyzer": "ik_max_word",
            		"search_analyzer": "ik_smart",
            		"fields": {  # 对于text类型的字段可以单独存储一份 用于后面的排序使用
              				"keyword": {
                				"type": "keyword",
                				"ignore_above": 256
              				}
            		}
				},
				"createTime": {
					"type": "date",
					"format": "yyyy-MM-dd HH:mm:ss" # 指定时间格式后,只能存储指定格式的时间,java中的date类型不能直接存储,需要转换成对应的类型
				},
				"updateTime": {
					"type": "date",
					"format": "yyyy-MM-dd HH:mm:ss"
				},
				"isDelete": {
					"type": "integer"
				}
			}
		}
}}

3、更新文档

# 自动生成唯一 _id :
POST /test/test
{
 "name":"我是谁,谁是我" 
}

# 返回结果:
{
  "_index": "test",
  "_type": "test",
  "_id": "gLKe4X4BLI5cjpF7njkO", //自动生成的id
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}

# 手动设置id
PUT /test/test/465?op_type=create
{
 "name":"我是谁,谁是我" 
}
或
PUT /test/test/465/_create
{
 "name":"我是谁,谁是我" 
}
如果创建新文档的请求成功执行则返回
{
  "_index": "test",
  "_type": "test",
  "_id": "465",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}
另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,Elasticsearch 将会返回 409 Conflict 响应码,以及如下的错误信息:
{
   "error": {
      "root_cause": [
         {
            "type": "document_already_exists_exception",
            "reason": "[blog][123]: document already exists",
            "shard": "0",
            "index": "website"
         }
      ],
      "type": "document_already_exists_exception",
      "reason": "[blog][123]: document already exists",
      "shard": "0",
      "index": "website"
   },
   "status": 409
}

4、更新文档

es文档是不可改变的,更新文档实际的操作是先查出旧文档的json,然后更新这个json,再删除旧文档,最后再新增一个新的文档
# 更新整个文档,如果文档字段不在更新字段中,则会被舍弃
PUT /test/test/465
{
  "title": "My first blog entry",
  "text":  "I am starting to get the hang of this...",
  "date":  "2014/01/02"
}
# 返回结果
{
  "_index": "test",
  "_type": "test",
  "_id": "465",
  "_version": 3,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 2,
  "_primary_term": 1
}

# 更新 文档的部分字段
POST /test/test/465/_update
{
   "doc" : {
      "tags" : [ "testing" ],
      "title": "天天向上"
   }
}
# 返回结果
{
  "_index": "test",
  "_type": "test",
  "_id": "465",
  "_version": 4,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}

5、删除文档

更具id删除文档
DELETE /website/blog/123
# 返回结果
{
  "_index": "test",
  "_type": "test",
  "_id": "uZOYM34BLI5cjpF7dwsz",
  "_version": 6,
  "result": "deleted",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 8,
  "_primary_term": 1
}
# 更具指定条件删除文档
POST test/_delete_by_query
{
  "query": {
    "match": {
      "name": "新浪军事22"
    }
  }
}
# 返回结果
{
  "took": 477,
  "timed_out": false,
  "total": 4,
  "deleted": 4,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}



6、条件查询

GET /test/test/_search
{
    "query" : {
        "match" : { 
            "name" : "我谁"
        }
    }
}
# 备注: match:分词匹配;
         match_phrase:精确匹配一系列单词或者_短语
         match_all: 匹配所有文档,相当于不做筛选
         match_phrase_prefix:  最左前缀查询
         multi_match: 多字段查询
         "multi_match": {
      			"query": "天天向上", 
      			"fields": ["title","text"]
    		}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值