Elastic Search 入门

Elastic Search 入门

安装Elastic Search#

安装成功之后验证

<code>curl -X GET http://localhost:9200/?pretty
{
"name" : "ZKKlE0t",
"cluster_name" : "es",
"cluster_uuid" : "sI09KISmQNaGMgbuN7S4gQ",
"version" : {
"number" : "6.6.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "1fd8f69",
"build_date" : "2019-02-13T17:10:04.160291Z",
"build_snapshot" : false,
"lucene_version" : "7.6.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}/<code>

分片#

分片是Elasticsearch在集群中分发数据的关键,分片是数据的容器,文档都存储在问片中,然后分片被分配到集群中的节点上, 当你的集群扩容或缩小,ES会自动在节点之间迁移分片, 使集群保持平衡

分片可以是主分片(primary shard)或者是复制分片。索引中每个文档属于一个单独的主分片,复制分片是主分片的一个单独的副本, 作为冗余数据,防止硬件故障导致数据丢失。

当索引创建完成时, 主分片的数量就固定了,但是复制分片的数量可以随时调整。

创建索引:

<code>curl -X PUT http://localhost:9200/blogs -H "Content-Type: application/json" -d '{ "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }'

> Response
{"acknowledged":true,"shards_acknowledged":false,"index":"blogs"}/<code>

启动多个node实例#

<code>elasticsearch -Epath.data=$ELASTIC_HOME/data/es1 -Epath.logs=$ELASTIC_HOME/logs/es1
elasticsearch -Epath.data=$ELASTIC_HOME/data/es2 -Epath.logs=$ELASTIC_HOME/logs/es2
elasticsearch -Epath.data=$ELASTIC_HOME/data/es3 -Epath.logs=$ELASTIC_HOME/logs/es3/<code>
<code>curl -X GET http://localhost:9200/_cluster/health/?pretty
{
"cluster_name" : "es",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 2,
"number_of_data_nodes" : 2,
"active_primary_shards" : 0,
"active_shards" : 0,
"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
}/<code>

其中status为green

颜色意义green所有分片和复制分片都可用yellow所有主要分片可用,但复制分片不是都可用red不是所有主要分片可用

数据结构#

一个文档除了信息数据之外还必须包括元数据,Elasticsearch中必须有如下元数据节点:

节点意义_index文档存储的地方_type文档代表对象的类_id文档的唯一标识

  • _index 索引类似与关系数据库里的数据库, 它是存储和索引关联数据的地方
  • _type 在关系型数据库中,我们将相同类的对象存储在一个表里,因为他们有相同的结构,在Elasticsearch中,我们使用相同类型(type)的文档表示相同的事物,他们的数据结构是相同的
  • _id 是一个字符串,与_index和_type组合时,就可以在Elasticsearch中唯一标识一个文档,当创建文档时,你可以自定义_id,也可由系统帮你生成

和关系型数据库做一个类比 Relational DB ⇒ Databases ⇒ Tables ⇒ Rows ⇒ Columns Elasticsearch ⇒ Indices ⇒ Types ⇒ Documents ⇒ Fields

基本操作#

假设我们的索引为blog,类型为post,

  • 创建索引

使用PUT方法时, 我们可以指定ID,如果希望系统自动生成, 可以使用POST

<code>**手动赋值ID**
curl -X PUT -H "Content-Type: application/json" \\
-d '{ "title": "First blog", "text": "Elastic search", "date": "2018/01/01" }' http://localhost:9200/blog/post

{
"_index" : "blog",

"_type" : "post",
"_id" : "123",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "First blog",
"text" : "Elastic search",
"date" : "2018/01/01"
}
}


**自动生成**

curl -X POST -H "Content-Type: application/json" \\
-d '{ "title": "First blog", "text": "Elastic search", "date": "2018/01/01" }' http://localhost:9200/blog/post

{
"_index" : "blog",
"_type" : "post",
"_id" : "dKg7KWkBMu7m9eCgyDUF",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "First blog",
"text" : "Elastic search",
"date" : "2018/01/01"
}
}/<code>
  • 检索文档

请求时追加pretty返回结果会对json进行格式化,如果响应内容中found为true表示文档存在,如果文档不存在同样会返回结果,found为false

<code>curl -X GET http://localhost:9200/blog/post/123?pretty
{
"_index" : "blog",
"_type" : "post",
"_id" : "123",

"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "First blog",
"text" : "Elastic search",
"date" : "2018/01/01"
}
}

curl -X GET http://localhost:9200/blog/post/1234?pretty
{
"_index" : "blog",
"_type" : "post",
"_id" : "1234",
"found" : false
}/<code>
  • 检索文档中的部分字段

GET 请求会返回文档的全部内容, 存储在_source,如果你只想显示部分字段,可以使用_source字段过滤

<code>curl -X GET http://localhost:9200/blog/post/123?pretty&_source=title,text

{
"_index" : "blog",
"_type" : "post",
"_id" : "123",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"text" : "Elastic search",
"title" : "First blog"
}
}/<code>
  • 检查文档是否存在

存在返回200,不存在返回404

<code>curl -I http://localhost:9200/blog/post/123
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 184/<code>
<code>curl -I  http://localhost:9200/blog/post/1234
HTTP/1.1 404 Not Found
content-type: application/json; charset=UTF-8
content-length: 59/<code>
  • 更新文档

更新文档时,原有文档会被标记为删除,不可访问,新文档版本号会+1

<code>curl -X PUT -H "Content-Type: application/json" http://localhost:9200/blog/post/123 -d '{ "title": "Update blog" }'

{
"_index" : "blog",
"_type" : "post",
"_id" : "123",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "Update blog"
}
}/<code>

局部更新

使用update API更新文档时,会接受一个局部文档参数doc,它会合并到现有文档中,对象合并在一起,已经存在的字段被覆盖, 新字段 则追加到原文档

<code>curl -X POST -H "Content-Type: application/json" http://localhost:9200/blog/post/123/_update -d '{ "doc": { "title": "Update partial blog", "views": 0 }}'

{

"_index" : "blog",
"_type" : "post",
"_id" : "123",
"_version" : 3,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "Update partial blog",
"views" : 0
}
}/<code>

文档冲突#

由于Elasticsearch是分布式结构的,每个文档可能存储在不同的分片上,当多个进程同时更新文档时可能会出现写冲突, 这时可能会出现脏数据。 类比关系型数据库中的写冲突解决方法

  • 悲观锁:假设任何情况下都会发生冲突,写数据时先请求锁,得到锁之后写数据,完成后释放锁
  • 乐观锁:假设不会造成冲突,直接去写, 写数据的时候进行版本比较,如果不一致,说明有其他进程修改过,抛出异常 我们可以通过版本号来解决Elasticsearch中的写冲突问题 在提交更新的时候加入版本号,如果版本号一致则修改,不一致则跳过
<code>curl -X POST -H "Content-Type: application/json" http://localhost:9200/blog/post/123?version=1 -d '{ "title": "Update partial blog", "views": 0 }'/<code>


分享到:


相關文章: