安装
官网下载es,下载完之后设置环境变量,es环境变量和本地Java环境变量一样。由于es的配置默认使用内置jdk,修改配置还是报错索性直接创建一个环境变量执行本机jdk,启动就不报错了。
基本概念
es中没有表的概念,以下对应MySQL的关系
Elasticsearch | MySQL |
索引(index) | 数据库(database) |
类型(type) | 表(table) |
文档(document) | 行(row) |
字段(field) | 列(column) |
映射 | 索引 |
GET http://... | select * from |
PUT http://... | update x set |
DELETE http://... | delete x |
type类似MySQL中表的概念,es中没有表的概念。在es6.0之前有type的概念,后来官方说这是设计上的一个失误,就从7.0开始移除了。
基本语法
创建索引
PUT http://127.0.0.1:9200/index
获取索引
GET http://127.0.0.1:9200/index
删除索引
DELETE http://127.0.0.1:9200/index
获取所有索引
GET http://127.0.0.1:9200/_cat/indices?v
添加数据
POST请求添加文档
post请求不是幂等性的,添加多次相同的数据返回的_id属性是不同的。
其中id属性是es随机生成的唯一标识。
POST http://127.0.0.1:9200/index/_doc
{
"name" : "张三",
"age" : 98
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "5CbSvI4BdeYO_vbj_Kx5",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
如果想要指定id添加的话只需要在路径后面跟上id就可以
POST http://127.0.0.1:9200/index/_doc/10300
{
"name" : "张三",
"age" : 98
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
PUT请求添加文档
PUT http://127.0.0.1:9200/index/_doc/10300
PUT http://127.0.0.1:9200/shopping/_create/10301
{
"name" : "张三",
"age" : 98
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 1
}
查询数据
根据文档id查询文档
GET http://127.0.0.1:9200/shopping/_doc/10300
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 3,
"_seq_no": 5,
"_primary_term": 1,
"found": true,
"_source": {
"name": "张三",
"age": "88"
}
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10302",
"found": false
}
查询索引下所有文档
http://127.0.0.1:9200/shopping/_search
但与指定一个文档 ID 不同,这次使用 _search 。返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回十条结果。
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "4ibSvI4BdeYO_vbj4qzm",
"_score": 1.0,
"_source": {
"name": "张三",
"age": "88"
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "4ybSvI4BdeYO_vbj96xe",
"_score": 1.0,
"_source": {
"name": "张三",
"age": "88"
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "5CbSvI4BdeYO_vbj_Kx5",
"_score": 1.0,
"_source": {
"name": "张三",
"age": "88"
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_score": 1.0,
"_source": {
"name": "张三",
"age": "88"
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "10301",
"_score": 1.0,
"_source": {
"name": "张三",
"age": "88"
}
}
]
}
}
根据条件查询
GET http://127.0.0.1:9200/shopping/_search?q=name:更新
{
"took": 36,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 2.1784627,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_score": 2.1784627,
"_source": {
"name": "张三更新",
"age": 66
}
}
]
}
}
使用表达式查询
Query-string 搜索通过命令非常方便地进行临时性的即席搜索 ,但它有自身的局限性(参见 轻量搜索 )。Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。
领域特定语言 (DSL), 使用 JSON 构造了一个请求。我们可以像这样重写之前的查询所有名为 Smith 的搜索 :
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": { // 过滤
"range" : {
"age" : { "gt" : 30 }
}
},
"sort" : { // 排序
"age" : {
"order" : "desc"
}
}
}
}
}
查询名字代更新的,只显示age和name两个字段。
由于添加数据的时候age用的字符串类型的,字符串不可以排序,就不做演示了
GET http://127.0.0.1:9200/shopping/_search
{
"query" : {
"match" : {
"name" : "更新"
}
},
"_source" : ["age","name"]
}
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 2.1784627,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_score": 2.1784627,
"_source": {
"name": "张三更新",
"age": 66
}
}
]
}
}
全文搜索
以下内容全部引用官方文档:
截止目前的搜索相对都很简单:单个姓名,通过年龄过滤。现在尝试下稍微高级点儿的全文搜索——一项 传统数据库确实很难搞定的任务。
搜索下所有喜欢攀岩(rock climbing)的员工:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
显然我们依旧使用之前的 match 查询在`about` 属性上搜索 “rock climbing” 。得到两个匹配的文档:
{
...
"hits": {
"total": 2,
"max_score": 0.16273327,
"hits": [
{
...
"_score": 0.16273327,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
},
{
...
"_score": 0.016878016,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [ "music" ]
}
}
]
}
}
相关性得分_score
Elasticsearch 默认按照相关性得分排序,即每个文档跟查询的匹配程度。第一个最高得分的结果很明显:John Smith 的 about 属性清楚地写着 “rock climbing” 。
但为什么 Jane Smith 也作为结果返回了呢?原因是她的 about 属性里提到了 “rock” 。因为只有 “rock” 而没有 “climbing” ,所以她的相关性得分低于 John 的。
这是一个很好的案例,阐明了 Elasticsearch 如何 在 全文属性上搜索并返回相关性最强的结果。Elasticsearch中的 相关性 概念非常重要,也是完全区别于传统关系型数据库的一个概念,数据库中的一条记录要么匹配要么不匹配。
修改数据
全量修改
PUT http://127.0.0.1:9200/shopping/_doc/10300
{
"name": "张三更新",
"age": "88"
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 6,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 9,
"_primary_term": 1
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 6,
"_seq_no": 9,
"_primary_term": 1,
"found": true,
"_source": {
"name": "张三更新",
"age": "88"
}
}
局部修改
因为PUT请求具有幂等性,所有局部修改用PUT请求就不是,用POST请求
POST http://127.0.0.1:9200/shopping/_update/10300
{
"doc":{
"age" : 66
}
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 7,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 10,
"_primary_term": 1
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "10300",
"_version": 7,
"_seq_no": 10,
"_primary_term": 1,
"found": true,
"_source": {
"name": "张三更新",
"age": 66
}
}