当前位置 > it书童 > elk > 正文
推荐小册
java高效编程
怎样更高效地用 java 编程

juc并发工具库
java并发编程工具库

设计模式
设计模式

jvm调优
jvm调优

rabbitmq实战
rabbitmq实战

redis实战
redis实战

Keepavlied高可用集群
Keepavlied高可用集群

nginx入门到实战
nginx入门到实战

java调试
java调试中遇到的各种坑

java输入输出流
java输入输出流

Elasticsearch 增删改查

elk it书童 2019-10-04 10:57:03 0赞 0踩 609阅读 0评论

在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。

创建/删除索引

# 创建空索引 指定分片数和副本数
PUT /heros
{
   "settings": {
      "index": {
         "number_of_shards": "2",
         "number_of_replicas": "0"
      }
   }
}

# 结果
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "heros"
}


# 删除索引
DELETE /heros

# 结果
{
  "acknowledged" : true
}

插入文档

指定 id 写入文档

# 写入文档
POST /heros/_doc/1
{
  "name": "杨过",
  "gender": "男",
  "skill": "黯然销魂掌",
  "age": 32
}

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

不指定 id

# 不指定主键 id ,es 会自动生成
POST /heros/_doc
{
  "name": "郭靖",
  "gender": "男",
  "skill": "降龙十八掌",
  "age": 52
}

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "qTbyOG0B3p3gGxF6LrY4",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

更新文档

在Elasticsearch中,文档数据是不能修改的,但是可以通过覆盖的方式进行更新。

# 更新数据
PUT /heros/_doc/1
{
  "name": "杨过",
  "gender": "男",
  "skill": "黯然销魂掌"
}

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}
# 查看更新后的数据
GET /heros/_doc/1

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "杨过",
    "gender" : "男",
    "skill" : "黯然销魂掌"
  }
}

问题来了,原来这个文档有 age 字段,在更新时被覆盖掉了,这显然不是我们想要的结果。我们希望在更新数据时,如果某些字段不传值,应该保持不变

要达到此目的,需要用 _update 操作

# 局部更新
POST /heros/_update/1
{
  "doc": {
    "skill": "玄铁剑法"
  }
}

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "noop",
  "_shards" : {
    "total" : 0,
    "successful" : 0,
    "failed" : 0
  }
}

# 查看更新后的数据
GET /heros/_doc/1

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "_seq_no" : 2,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "杨过",
    "gender" : "男",
    "skill" : "玄铁剑法"
  }
}

删除文档

在 Elasticsearch 中,删除文档数据,只需要发起 DELETE 请求即可

# 删除文档
DELETE /heros/_doc/1

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}
# 删除一条不存在的数据
DELETE /heros/_doc/2

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "not_found",
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}

搜索数据

# 获取所有数据
GET /heros/_search

# 结果
{
  "took" : 614,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 1.0,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        }
      }
    ]
  }
}

# 根据 _id 主键获取数据
GET /heros/_doc/qTbyOG0B3p3gGxF6LrY4

# 结果
{
  "_index" : "heros",
  "_type" : "_doc",
  "_id" : "qTbyOG0B3p3gGxF6LrY4",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "郭靖",
    "gender" : "男",
    "skill" : "降龙十八掌",
    "age" : 52
  }
}
# 初始化一些数据

POST /heros/_doc
{
  "name": "段誉",
  "gender": "男",
  "skill": "六脉神剑",
  "age": 22
}

POST /heros/_doc
{
  "name": "萧峰",
  "gender": "男",
  "skill": "降龙十八掌",
  "age": 30
}

POST /heros/_doc
{
  "name": "小龙女",
  "gender": "女",
  "skill": "玉女心经",
  "age": 28
}

# 搜索 age 为 22 的数据
GET /heros/_search?q=age:22

# 结果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qjYKOW0B3p3gGxF6OLab",
        "_score" : 1.0,
        "_source" : {
          "name" : "段誉",
          "gender" : "男",
          "skill" : "六脉神剑",
          "age" : 22
        }
      }
    ]
  }
}

DSL搜索

Elasticsearch提供丰富且灵活的查询语言叫做 DSL查询(Query DSL), 能够构建更加复杂强大的查询。

DSL(Domain Specific Language特定领域语言) 以JSON请求体的形式出现。

# 查询 age > 25 且 gender 为 男 的数据
POST /heros/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "age": {
            "gt": 25
          }
        }
      },
      "must": {
        "match": {
          "gender": "男"
        }
      }
    }
  }
}

# 结果
{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.6931472,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 0.6931472,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qzYKOW0B3p3gGxF6T7bF",
        "_score" : 0.18232156,
        "_source" : {
          "name" : "萧峰",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 30
        }
      }
    ]
  }
}

# 全文搜索
POST /heros/_search
{
  "query": {
    "match": {
      "name": "萧 靖"
    }
  }
}

# 结果
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.75491273,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 0.75491273,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qzYKOW0B3p3gGxF6T7bF",
        "_score" : 0.6931472,
        "_source" : {
          "name" : "萧峰",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 30
        }
      }
    ]
  }
}

高亮显示

# 高亮显示
POST /heros/_search
{
  "query": {
    "match": {
      "name": "郭靖"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

# 结果
{
  "took" : 291,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.5098255,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 1.5098255,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        },
        "highlight" : {
          "name" : [
            "<em>郭</em><em>靖</em>"
          ]
        }
      }
    ]
  }
}

聚合

在Elasticsearch中,支持聚合操作,类似SQL中的group by操作。

# 聚合
POST /heros/_search
{
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "age"
      }
    }
  }
}


# 结果
{
  "took" : 41,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qjYKOW0B3p3gGxF6OLab",
        "_score" : 1.0,
        "_source" : {
          "name" : "段誉",
          "gender" : "男",
          "skill" : "六脉神剑",
          "age" : 22
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qzYKOW0B3p3gGxF6T7bF",
        "_score" : 1.0,
        "_source" : {
          "name" : "萧峰",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 30
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 1.0,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "rDYKOW0B3p3gGxF6WrYB",
        "_score" : 1.0,
        "_source" : {
          "name" : "小龙女",
          "gender" : "女",
          "skill" : "玉女心经",
          "age" : 28
        }
      }
    ]
  },
  "aggregations" : {
    "all_interests" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 22,
          "doc_count" : 1
        },
        {
          "key" : 28,
          "doc_count" : 1
        },
        {
          "key" : 30,
          "doc_count" : 1
        },
        {
          "key" : 52,
          "doc_count" : 1
        }
      ]
    }
  }
}
关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/75/elasticsearch