名词解释
索引:类似RDMS的数据库
类型:类似于关系型数据库中的表
文档:类似于关系型数据库中的一行
字段:类似于关系型数据库中表的某一个属性
常见操作
文档的建立
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
response:
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},-
"_seq_no": 0,
"_primary_term": 1
}
新增一个字段创建,下表中的school
字段
PUT /megacorp/employee/2
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"school": "ouc",
"interests": [ "sports", "music" ]
}
response:
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},-
"_seq_no": 0,
"_primary_term": 1
}
只有不存在的时候才创建
PUT /website/blog/123?op_type=create
PUT /website/blog/123/_create
自动ID生成
POST /megacorp/employee
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"school": "ouc",
"interests": [ "sports", "music" ]
}
文档查询
GET /megacorp/employee/2
{"_index":"megacorp",
"_type":"employee",
"_id":"2",
"_version":1,
"found":true,
"_source":{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"school": "ouc",
"interests": [ "sports", "music" ]
}}
查询某几个字段
GET /megacorp/employee/1?_source=about,age,title
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"about": "I love to go rock climbing",
"age": 25
}-
}
只查询source数据
GET /megacorp/employee/1/_source
一次获取多个查询字段(_source字段只能用来标注一个字段)
GET /_mget
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
}
//多个处于同一个索引和类型下的直接用ids
GET /website/blog/_mget
{
"ids" : [ "2", "1" ]
}
搜索查询
GET /megacorp/employee/_search?q=school:ouc
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [(1)
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 0.2876821,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"school": "ouc",
"interests": [(2)
"sports",
"music"
]
}
}
]
}
}
GET请求也能支持body体的传输,有些工具比如PostMan也不支持,可以通过curl来进行验证
curl -X GET 'http://localhost:9200/megacorp/employee/_search' -d '{"query":{"match":{"school":"ouc"}}}' -H 'Content-Type: application/json'
**response**
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 0.2876821,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"school": "ouc",
"interests": ["sports", "music"]
更多复杂的查询条件
{
"query" : {
"bool": {
"must": {
"match" : {
"school": "ouc"
}
},
"filter": {
"range" : {
"age" : { "gt" : 20 }
}
}
}
}
}
原始的SQL语句:
SELECT product
FROM products
WHERE (price = 20 OR productID = "XHDK-A-1293-#fJ3")
AND (price != 30)
GET /my_store/products/_search
{ "query" :
{ "filtered" :
"filter" : {
"bool" : {
"should" :
[ { "term" : {"price" : 20}},
{ "term" : {"productID" : "XHDK-A-1293-#fJ3"}}
],
"must_not" :
{ "term" : {"price" : 30}
}
}
}
}
}
}
嵌套的bool表达式
SELECT document
FROM products
WHERE productID = "KDKE-B-9947-#kL5"
OR ( productID = "JODL-X-1937-#pV7"
AND price = 30 )
GET /my_store/products/_search
{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"should" : [
{ "term" : {"productID" : "KDKE-B-9947-#kL5"}},
{ "bool" : {
"must" : [
{ "term" : {"productID" : "JODL-X-1937-#pV7"}},
{ "term" : {"price" : 30}}
]
}}
]
}
}
}
}
}
多值包含: price为20或者30的文档
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"terms" : {
"price" : [20, 30]
}
}
}
}
}
全文检索
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"about": "love"
}
},
"filter": {
"range" : {
"age" : { "gt" : 20 }
}
}
}
}
}
短语查询:只返回完全包含的场景
{
"query": {
"match_phrase": {
"about": "love you"
}
}
}
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
聚合分析
分析interests
字段各个分词命中的文档数以及年龄字段聚合得到的平均年龄
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
response
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2,
"avg_age": {
"value": 28.5
}
},
{
"key": "forestry",
"doc_count": 1,
"avg_age": {
"value": 35
}
},
{
"key": "sports",
"doc_count": 1,
"avg_age": {
"value": 25
}
}
]
}
需要提前开启把数据加载到内存中的操作
PUT /megacorp/_mapping/employee/
{
"properties": {
"interests": {
"type": "text",
"fielddata": true
}
}
}
同时开启query和aggs查询
GET /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}
创建索引
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
response:
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "blogs"
}
上面的例子创建了一个名为blogs
的索引,其中包含3个主分片,副本数为1。默认索引创建时5个主分片,一个副本。
版本冲突控制
为了防止多个写入程序冲突出现相互覆盖干扰的情况,需要通过版本号来进行控制
PUT /megacorp/employee/1?version=2
{
"age":2
}
上述的更新操作只有在ES中的文档的版本是2的情况下才能更新成功,可以通过外部版本的方式来完成只要传入版本不小于ES中保存的版本时才完成更新操作,同时版本会变更为传入的版本号
PUT /megacorp/employee/1?version=2&version_type=external
部分更新
POST /megacorp/employee/1/_update
{
"age":1
}
POST /website/pageviews/1/_update?retry_on_conflict=5
GET /_cluster/health
response:
{
"cluster_name": "ljh",
"status": "yellow",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 8,
"active_shards": 8,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 8,
"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": 50
}
unassigned
字段表示有8个分片待分片副本,由于就一个节点,所有将副本分配到同一个节点的意义不大。
索引的主分片数量在创建的时候就确定了,后续不能再修改,副本数可以修改
修改索引blogs
的副本数量
PUT /blogs/_settings
{
"number_of_replicas":2
}
批量操作
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }} [](https://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/bulk.html#CO16-1)![image](http://upload-images.jianshu.io/upload_images/4906916-691921c22000fe88.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} }
聚合操作
{
"query": {
"bool": {
"must": [
{
"terms": {
"model": [
"LM358",
"BU406",
"BAV99"
]
}
}
],
"must_not": [],
"should": []
}
},
"from": 0,
"size": 0,
"sort": [],
"aggs": {
"types_count": {
"terms": {
"field": "model"
},
"aggs": {
"brand": {
"terms": {
"field": "brand"
},
"aggs": {
"upbymemberid": {
"cardinality": {
"field": "upByMemberID"
}
}
}
}
}
}
}
}