一:索引相關
1,創建索引
(1) PUT /test_index/
{
"settings":{
"index":{
"number_of_shards":3,
"number_of_replicas":0
}
}
}
(2)創建索引的同時手動創建mapping(一般添加數據的時候,mapping可以自動創建,_routing 表示自定義路由,默認是以id爲路由,只有在特殊用法的情況下才需要自定義路由,如果不指定路由自定,默認查所有分片,然後聚合返回結果)
PUT /test_index/
{
"settings":{
"index":{
"number_of_shards":3,
"number_of_replicas":0
}
},
"mappings":{
"user3":{
"_routing":{
"required":true
},
"properties":{
"name":{"type":"text"},
"age":{"type":"long"},
"date":{"type":"date","index":false}
}
}
}
}
(3)也可以直接用 PUT test_index2 (添加索引,用默認配置,注意put要大寫)
2:查看索引
(1),查看集羣健康:GET /_cat/health?v
(2),查看所有索引:GET /_cat/indices?v
(3),查看某個索引信息:GET /test_index/_settings/
(4),查看所有索引信息 GET /_all/_settings
(7)GET /test_index1/user/_mapping 來查看mapping
(6)GET /test_index/_settings?flat_settings=true (flat_settings=true 參數通過對象.屬性的方式返回設置信息)
(5)查看集羣狀態 GET /_cluster/state(後面可以加上filter_path參數來指定返回哪些字段)
(5)查看集羣狀態 GET /_cluster/settings
3: 刪除索引:
DELETE test_index
二:文檔相關curd
1:插入
(1),PUT /test_index/user1/1 (user1 表示索引下的類型,這個類型是我們自定義的,1 表示id,用put 方法必須指定id
(put是更新,如果沒有的話就插入))
{
"name":"zhangsan",
"age":30
}
(2)可以通過op_type參數來指定,強制創建索引(如果索引已經存在的話會返回失敗)第二種是通過 (PUT test_index/user/1/_create)
PUT test_index/user/1?op_type=create
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
(2),POST /test_index/user1/ (如果不指定id 的話,id就由es 生成,那麼就要用post方法)
{
"name":"zhangsan",
"age":30
}
2:刪除某個文檔
(1),DELETE /test_index/user1/1 (刪除id=1 的)
(2) DELETE /test_service1/user1/1?wait_for_active_shards=3&timeout=5s (wait_for_active_shards通過這個參數可以控制有幾個節點可用時再操作)
(3) POST /test_service1/user1/_delete_by_query (刪除符合查詢條件的)
{
"query":{
"match":{
"content":"zhaoliu"
}
}
}
也可以用 POST /test_service1/user1/_delete_by_query?q=content:liqi (這種方式)
(_delete_by_query 在開始文檔刪除時,先獲取一個快照,再刪除,如果這兩步之間文檔的版本發生變化時,刪除會失敗,會發生版本衝突
將會發生多次搜索,然後刪除,如果有的成功了,有的失敗了,失敗的會返回)
(4)POST /test_service1/user1/_delete_by_query (刪除所有文檔)
{
"query": {
"match_all": {}
}
}
(5) POST /test_index1/user1/_delete_by_query?routing=wangwu (如果刪除的時候指定了路由,只會刪除指定路由上的數據,即使查詢的是所有)
{
"query":{
"match_all":{}
}
}
(6)POST twitter/_delete_by_query?scroll_size=5000 (默認使用的scroll_size爲1000,一次刪1000條?)
{
"query": {
"term": {
"user": "kimchy"
}
}
}
(7) _delete_by_query 還支持這些參數(refresh, wait_for_completion, wait_for_active_shards, timeout, and scroll)
(8) POST twitter/_delete_by_query?conflicts=proceed (conflicts=proceed 在出現錯誤是,繼續執行後面的,而不是終止)
{
"query": {
"match_all": {}
}
}
三:修改記錄
(1),put是更新,如果沒有的話就插入(這個是覆蓋的方式,就是必須要加上所有的字段,如果只要更新某一個字段,就要用post 方法如下:)
(2),跟新某個字段,如下把id=1 的年齡改爲100 : (有就修改,沒有就新增)
POST /test_index/user1/1/_update
{
"doc":{
"age":100
}
}
(3) POST /test_service1/user1/1/_update (如果名字本來就是zhangsan的話,這個操作想當與沒做任何修改,es不會去執行,
返回結果中有noop表示空操作,版本號也不會更新,如果想更新版本號的話就加上 "detect_noop": false)
{
"doc":{
"name":"zhangsan"
},
"detect_noop": false
}
(4),POST /test_service1/user1/_update_by_query?conflicts=proceed (這一種,只有查詢,沒有更新體的,只會更新版本號)
{
"query":{
"term":{
"name":"zhangsan"
}
}
}
(5) POST /test_service1/user1/1/_update (腳本更新文檔,lang表示用何種腳本,painless表示es內置腳本,還有pyton,js等)
{
"script":{
"source":"ctx._source.age=ctx._source.age+params.aaa",
"lang":"painless",
"params":{
"aaa":11
}
}
}
(6)更新數組
先插入帶數組的數據
PUT /test_service1/user1/6
{
"name":"zhangliu",
"age":60,
"content":"zhangliu love apple",
"likes":["apple","banana"]
}
更新(添加一條)
POST /test_service1/user1/6/_update
{
"script": {
"source":"ctx._source.likes.add('graps')",
"lang": "painless"
}
}
或者使用參數的方式
POST /test_service1/user1/6/_update
{
"script": {
"source":"ctx._source.likes.add(params.aaa)",
"lang": "painless",
"params":{
"aaa":"orange"
}
}
}
(7)刪除 (注意remove 參數只能是 索引號,如果只包含腳本的話,script後面就沒有花括號,要包含lang,params等就要包含花括號)
POST /test_service1/user1/6/_update
{
"script": {
"source":"if(ctx._source.likes.contains(params.aaa)){ctx._source.likes.remove(ctx._source.likes.indexOf(params.aaa))}",
"lang": "painless",
"params":{
"aaa":"orange"
}
}
}
除了 _source 通過ctx可以訪問的還有 index, _type, _id, _version, _routing and _now
(8) 可以對指定文檔添加一個字段
POST test_service1/user1/1/_update
{
"script" : "ctx._source.name = 'zhangsan'"
}
也可對指定文檔刪除一個字段
POST /test_service1/user1/1/_update
{
"script":"ctx._source.remove('name')"
}
(8) 還可以刪除(op=delete,下面就是如果id爲1 的記錄中 name=zhangsan,那麼刪除這條記錄,如果不符合條件的話,就只會增加版本號)
POST test_service1/user1/1/_update
{
"script":"if(ctx._source.name=='zhangsan'){ctx.op='delete'}"
}
(9) 如果這個id的文檔不存在的話,就會插入 upsert 中的內容
POST test_service1/user1/7/_update
{
"script":"ctx._source.name='lisi'",
"upsert":{
"name":"zhangsan7",
"age":70,
"content":"zhangqi love grape"
}
}
(10)如果 想 id爲8 的文檔 不存在的話,就插入 script中的內容,而不是插入 upsert中的內容的話,就設置 "scripted_upsert": true,
POST /test_service1/user1/8/_update
{
"scripted_upsert": true,
"script": {
"source":"ctx._source.likes=params.likes",
"params": {
"likes":["apple","grape"],
"content":"zhangsan8 like apple"
}
},
"upsert": {}
}
(11) 通過將 doc_as_upsert":true 設置爲true 可以在文檔不存在時可以插入doc中的內容(正常情況下id爲9 的不存在的話,去更新會報錯)
POST test_service1/user1/9/_update
{
"doc":{
"name":"zhang9"
},
"doc_as_upsert":true
}
2,_update_by_query(批量更新,更新時獲取的索引的快照,這意味着 獲取索引快照後,更新前,數據可能改變,這是更新將終止
後面的所有元素都做爲失敗元素返回(在failures字段中返回),如果想,衝突時繼續執行後面的記錄 可以 加上參數 conflicts=proceed)
(1),名字爲張三的都改爲李四(這個更新即使 query中的name就是李四 也會更新(版本號)不會有noop空操作,這個和 _update 不一樣 _update不會更新版本號,會返回noop空操作)
如果不想更新版本號可以在 script後加上ctx.op='noop'表示允許空操作,如果想刪除 query查詢的文檔可以 在scirpt 中設置 ctx.op='delete'
可以在url後加上routing字段路由到指定的分片上,默認情況下滾動查詢批次爲1000 可以使用scroll_size=100 來指定一次查多少(也就是更新多少)
還可以 使用 pipeline 來指定管道(?待辦,還有 throttling 代辦,requests_per_second 代辦) _update_by_query 還支持這些參數( pretty, refresh, wait_for_completion, wait_for_active_shards, timeout and scroll)
(scroll表示搜索的存活時間默認5分鐘 scroll=10m 10分鐘)
POST /test_index1/_update_by_query
{
"script": {
"source": "ctx._source.name='lisi';ctx.op='noop'",
"lang": "painless"
},
"query": {
"term": {
"name": "zhangsan"
}
}
}
4:查看
(1),GET /test_index/user1/1 (查看指定索引下,指定類型,指定id=1的記錄)
(2),GET /test_index/user1/1?_source=name,age (就是mysql 的 select name,age where id=1)
七:批量獲取
下面這四個方法只對 id的能這樣寫?,id 換成其他字段就不行了
1,(指定索引,類型,id)
GET /_mget/
{
"docs":[
{
"_index":"test_index1",
"_type":"user1",
"_id":1
},
{
"_index":"test_index2",
"_type":"user2",
"_id":1
}
]
}
2,也可以指定獲取的列(select name,, 獲取多個列的話就是 "_source":["name","age"])
GET /_mget/
{
"docs":[
{
"_index":"test_index1",
"_type":"user1",
"_id":1,
"_source":"name"
},
{
"_index":"test_index2",
"_type":"user2",
"_id":1,
"_source":"name"
}
]
}
3,獲取同索引同類型下的不同文檔(上面是獲取不同索引,不同類型下的文檔,6.x以後同一個索引下只有一個type)
GET /test_index/user1/_mget
{
"docs":[
{
"_id":1
"_source":"name"
},
{
"_id":1
"_source":"name"
}
]
}
4,也可以進一步簡化(注意和上面的對比,少了docs, 並且id 是ids 而不是_id)
GET /test_index1/user1/_mget
{
"ids":[1,2]
}
5,bulk 批量操作(能批量添加,修改,刪除,而上面的mget只能批量查詢)
模式:
{action:{metadata}}
{requestBody}
其中
action表示行爲有(create,index,update,delete, create和index表示創建文檔,create是文檔不存在時,創建,
如果文檔存在時,create就會報錯,index,是沒有就創建,有就替換)
metadata 表示具體數據,也就是我們要添加的,修改的,刪除的跟新的文檔數據,有 index,type,id
requestBody 表示請求體,(注意刪除是沒有請求體的)
(1)批量添加
POST /test_index1/user1/_bulk
{"index":{"_id":3}}
{"name":"wangwu","age":30}
{"index":{"_id":4}}
{"name":"zhaoliu","age":40}
注意,這裏面的請求體裏面沒有包含索引,和類型信息,就表示使用url中的,如果包含的話,就是新建索引
如下新建了,test_index2 索引,類型user2
POST /test_index1/user1/_bulk
{"index":{"_index":"test_index2","_type":"user2","_id":1}}
{"name":"zhangsan","age":20}
(2)刪除
POST /test_index1/user1/_bulk
{delete:{"_index":"test_index1","_type":"user1","_id":1}}
(3)修改
POST /test_index1/user1/_bulk
{"update":{"_index":"test_index1","type":"user1","_id":1}}
{"doc":{"age":100}}
總結: bulk 一次能處理多大的數據量取決於硬件,因爲bulk 是把要處理的數據放入內存中的,一般建議1000-5000
5-15M 最大不能超過100M,可以在es的配置文件中配置
九,es 版本控制
(1)內部版本控制:es內部的版本控制是通過樂觀鎖來控制的(必須版本號相等纔行,和mysql一樣)_version 比如下面修改版本號爲3 的記錄
PUT /test_index1/user1/1?version=3
{
"name":"zhangsan",
"age":30
}
(2)外部版本控制:比如當有這樣一種需求,mysql版本號用時間戳來表示,但是我們想把mysql的數據,導入到es中,
這個時候我們可以用外部版本號(就是把es中的版本號替換成我們url中提供的版本號),只有外部版本號大於es中的
版本號才能成功比如下面,假如es中內部的版本號爲1,我們提供的版本號爲 20181222 那麼會把es中的版本號
1,替換成 20181222 注意後面的參數version_type=external 表示外部版本號
PUT /test_index1/user1/1?version=20181222&version_type=external
{
"name":"zhangsan",
"age":30
}
九:mapping
(1)當我們創建文檔的時候,比如 PUT /test_index1/user1/1 的時候,es 不僅爲我們創建了索引index,和類型type
還爲我們自動創建了mapping 可以通過下面的語法查詢mapping
GET /test_index1/user/_mapping 來查看mapping
(2)手動創建mapping:如果自動創建mapping可以滿足要求的話,就不必手動創建mapping
如果要手動創建mapping的話,可以按下面語法創建(注意下面的"index":false 是mapping的一個屬性表示不索引,es
默認情況下會爲每一個字段都創建 索引,有些沒必要創建索引的,就不用創建索引)
{
"settings":{
"index":{
"number_of_shards":3,
"number_of_replicas":0
}
},
"mappings":{
"user3":{
"properties":{
"name":{"type":"text"},
"age":{"type":"long"},
"date":{"type":"date","index":false}
}
}
}
}
基本查詢######################################
十 es的基本查詢(query查詢)
query_string(查詢)
1, GET /test_index/user/_search?q=name:zhangsan&sort=name:desc
2,分頁查詢 : GET/test/_index/user/_search?from=0&size=2 (從0開始查2個)
3,可以通過filter_path 指定返回哪些字段 GET/test/_index/user/_search?filter_path=took,hits.hits
只能到_source一級,不能再往下了(注意和_source的區別)
//1,term 查詢(查詢條件只能是一個字段)
(1)GET /test_index/user/_serach
{
"query":{
"term":{"name":"zhangsan"}
}
}
//2,terms 查詢查詢張三或李四(查詢條件只能有一個字段)
(2)GET /test_index/user/_serach
{
"query":{
"terms":{"name":["zhangsan","lisi"]}
}
}
//2,from表示從哪個文檔開始,size表示查幾個,就是mysql中的分頁
(3)GET /test_index/user/_serach
{ "from":0,
"size":10,
"query":{
"terms":{"name":["zhangsan","lisi"]}
}
}
//2,如果想獲取版本號 加上 version:true 就行
(4)GET /test_index/user/_serach
{ "from":0,
"size":10,
"version":true,
"query":{
"terms":{"name":["zhangsan","lisi"]}
}
}
//3,match 查詢(查詢條件也只能是一個字段,和term 查詢的區別是 match可以進行分詞)
//zhangsan lisi 會進行分詞成zhangsan, lisi,(注意和term 查詢的區別,term 查詢的時候,查詢條件不會分詞,比如有條記錄 是 zhangsan and lisi, term查詢條件爲zhangsan,那麼也會把這條記錄查詢出來,),而match 會對查詢條件進行分詞)
(3)GET /test_index/user/_serach
{
"query":{
"match":{"name":"zhangsan lisi"}
}
}
//查詢年齡爲30 的
(2)GET /test_index/user/_serach
{
"query":{
"match":{"age":"30"}
}
}
//查詢 所有
(3)GET /test_index/user/_serach
{
"query":{
"match_all":{}
}
}
//4,查詢 多個字段(查詢name 或 age 的值爲 zhangsan 的)
(1)GET /test_index/user/_serach
{
"query":{
"multi_match":{
"query":"zhangsan",
"fields":["name","age"]
}
}
}
//4,短語查詢,也就是 mysql 中的 like %value% 比如下面 就是查%zhangsan,lisi% (相當於不分詞了)
(2)GET /test_index/user/_serach
{
"query":{
"match_phase":{
"name":"zhangsan,lisi"
}
}
}
//指定返回字段 通過_source 也就是mysql 中的 select 列
(6)GET /test_index/user/_serach
{ "_source":["name","age"]
"query":{
"name":"zhangsan"
}
}
//通過includs ecludes 來指定包含哪些字段,排除哪些字段
(7)GET /test_index/user/_serach
{
"query":{
"match_all":{}
}
"_source":{
"includes":["name","age"],
"ecludes":["score","grade"]
}
}
//通過includs ecludes 來指定包含哪些字段,排除哪些字段(可以使用通配符)
(7)GET /test_index/user/_serach
{
"query":{
"match_all":{}
}
"_source":{
"includes":"nam*",
"ecludes":["score","grade*"]
}
}
4,排序:
//根據年齡升序
1,GET /test_index/user/_search
{
"query":{
"match_all":{}
},
"sort":{"age":{"order":"desc"}}
}
5,//前綴查詢(prefix)(前綴是 wangwu的,
比如 zhangsan wangwu is man(這個存的時候會進行分詞),這個也會查出來)
GET /test_index/user/_search
{
"query":{
"match_phrase_prefix": {
"name": "wangwu"
}
}
}
6,//範圍查詢 (range)
參數 有 from,to,incluse_lower,include_upper,boost
include_lower是否包含左邊界,默認true,
include_upper 是否包含右邊界,默認true
(新版本的直接用 gte 和lte了?)
GET /test_index/user/_search
{
"query": {
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}
7,通配符查詢(wildcar 查詢 *(0個或多個) 或?(一個字符),下面直接用 "name":"aaa*"這種格式也行)
GET /test_index/user/_search
{
"query":{
"wildcard": {
"name": {
"value": "zhangsan*"
}
}
}
}
8,模糊查詢(fuzzy)
GET /test_index/user/_search
{
"query": {
"fuzzy": {
"name": "lisi"
}
}
}
9,filter查詢(filter查詢不計算相關度,可以緩存,速度快與query查詢)
GET /test_index/user/_search
{
"query": {
"bool": {
"filter": {
"term": {
"name": "zhangsan"
}
}
}
}
}
//張三或李四
GET /test_index/user/_search
{
"query": {
"bool": {
"filter": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
}
}
// 多個條件合再一起
GET /test_index/user/_search
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gte": 10,
"lte": 30
}
}
}
}
}
}
10,bool 查詢 (must(sql 中and) should (sql中的or) must_not (sql 中的 not))
(比如下面查的就是 age=30 或name="zhangsan"的,且 name !="lisi",也就是should裏面是or 關係)
GET /test_index/user/_search
{
"query":{
"bool": {
"should": [
{"term":{
"age":30
}},
{
"term": {
"name":"zhangsan"
}
}
],
"must_not": [
{"term":{
"name":"lisi"
}}
]
}
}
}
//裏面還可以再嵌套bool
GET /test_index/user/_search
{
"query":{
"bool": {
"should": [
{"term":{
"age":30
}},
{
"bool": {
"must": [
{"term": {
"age":10
}},
{
"term": {
"name":"zhangsan"
}
}
]
}
}
]
}
}
}
//查詢 某個字段不爲空的 (也就是sql 中的 is not null)(如下,查詢字段age不爲空的)
GET /test_index/user/_search
{
"query": {
"bool": {
"filter": {
"exists": {
"field": "age"
}
}
}
}
}
11.聚合查詢(sql 中的 sum avage 等)
//下面的 aggs //是固定的表示聚合查詢,sumage,是自己隨便取的一個名字,用來存儲查詢結果
//這個會把結果和每一條都查出來(默認20條?),但是我們一般只關心結果,
//可以在aggs上面,加一個 size:0 字段,表示只要聚合查詢的結果
GET /test_index/user/_search
{
"aggs":{
"sumage":{
"sum": {
"field": "age"
}
}
}
}
//cardinality (基數,像sql中的,分組後,有多少組)
GET /test_index/user/_search
{
"aggs":{
"geshu":{
"cardinality": {
"field": "age"
}
}
}
}
//分組 (相當於 sql中group by) 用terms 關鍵字(sss 同上面一樣,自己隨便
//取個名,來存結果)
GET /test_index/user/_search
{
"aggs": {
"sss": {
"terms": {
"field": "age"
}
}
},
"size": 0
}
//查詢出名字是張三的,然後根據年齡分組,然後,查出每一組的平均值
// group_self,avg_self (同上面一樣表示自己定義一個字段,用來存儲,查詢結果)
GET /test_index/user/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"aggs": {
"group_self": {
"terms": {
"field": "age"
},
"aggs":{
"avg_self":{
"avg": {
"field": "age"
}
}
}
}
}
}
//同上面一樣,查詢出名字是張三的,然後根據年齡分組,然後,
//查出每一組的平均值,然後按平均值avg_self 降序排序
GET /test_index/user/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"aggs": {
"group_self": {
"terms": {
"field": "age",
"order": {
"avg_self": "desc"
}
},
"aggs":{
"avg_self":{
"avg": {
"field": "age"
}
}
}
}
}
}
)
四:通用
1,可以通過filter_path 來返回查詢結果中的哪些字段
GET /test_service3/user3/_search?q=*&filter_path=timed_out,took,hits.hits
2, es深度分頁問題。
3,當對響應時間有有要求的時候後,可以加參數 timeout=10ms 等,返回已經查到的數據,
GET /test_index/user/_search?timeout=10ms
4,可以通過explain=true,來查看如果計算相關度分數的
GET /test_indx/user1/_search?explain=true
5,可以通過 GET/test_index/user1/_explain?q=name:zhangsan 來查看 query子句的查詢時否存在,不存在返回false,
6,docValues 是es爲數字,和日期(非字符串)類型創建的,正排索引,對排序,分組,等一些聚合操作能
提升性能,默認是對不分詞字段啓用的,,對分詞字段無效,(分詞字段需要在mapping中把fielddata設置爲true)
7,PUT /test/_doc/1?refresh (refresh 爲空 或 refresh=true將會立即刷新,refresh=wait_for 將會等待刷新後返回,refresh=false 不會刷新,等待系統默認刷新
index.refresh_interval配置的默認值是1s)
22,字符串排序問題,用字符串排序的時候會出錯,因爲es會進行分詞,索引字符串默認是不能排序的,如果想要排序,需要創建兩個索引項,一個用於搜索,一個不分詞,用於排序,,(注意下面的name字段中的fields,keyword表示不分詞),還要把fielddata設置爲true,這樣設置後這個name字段即可以用於搜索,也可以用於排序了,但是如果在查詢語句中直接使用
"sort":[{"name":{"order":"desc"}}] 這樣的話,排序是按照分詞後的詞進行排序的,應該在name後加個raw
也就是 "sort":[{"name.raw":{"order":"desc"}}] 這樣就可以排序了(raw表示使用原始的文本進行排序)
PUT / test_index1 /
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 0
}
},
"mappings": {
"user3": {
"properties": {
"name": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
},
"fielddata":true
}
},
"age": {
"type": "long"
},
"content": {
"type": "text"
},
"date": {
"type": "date",
"index": false
}
}
}
}
}
10,es copy_to 在創建索引的時候就要指定。比如 GET/test_index/user/_serach?q=zhangsan,lisi
這個查詢下沒有字段名,只有字段值,es在查詢時,會去每一個字段中去查找,zhangsan,或lisi(也 就是會分詞?)
數據量大的時候效率很低,爲此es提供了copy_to(可以把其他字段的值,鏈接到一起,查的時候就從這一個字段中查),
我們在創建mapping的時候要指定:如下(就會把name,content,複製到copy_fields字段上) 注意能被copy_to的字段必須是文本類型的
PUT /test_index1/
{
"settings":{
"index":{
"number_of_shards":3,
"number_of_replicas":0
}
},
"mappings":{
"user3":{
"properties":{
"name":{"type":"text","copy_to":"copy_fields"},
"age":{"type":"long"},
"content":{"type":"text","copy_to":"copy_fields"},
"date":{"type":"date","index":false}
}
}
}
}
查詢的時候 GET/test_index1/user1/_search?q=copy_filelds:zhangsan,lisi 就會從copy_filelds
這個字段中去查詢
11,GET twitter/_doc/1?stored_fields=tags,counter 通過 store 屬性 ,來獲取 store的字段,store爲false的將會查不到
PUT twitter
{
"mappings": {
"_doc": {
"properties": {
"counter": {
"type": "integer",
"store": false
},
"tags": {
"type": "keyword",
"store": true
}
}
}
}
}
PUT twitter/_doc/1
{
"counter" : 1,
"tags" : ["red"]
}
12, HEAD /test_index/user1/1 查看id爲1 的文檔是否存在
13, GET /test_index/user1/1?realtime=false (如果文檔已經更新,但還沒有刷新,get內部會調用 refresh,刷新數據,realtime改爲false 將不刷新)
14,GET /test_service1/user1/1?_source=false GET 默認會返回_source字段,可以通過 _source 設爲false 不檢索 _source字段
15,GET /test_service1/user1/1?_source_include=age,name 可以通過(_source_include,_source_exclude 來包含或者排除某些字段(也可以直接用_source=name,age 來包含某些字段)
16,GET twitter/_doc/1/_source (直接返回source字段)
17,HEAD twitter/_doc/1/_source(測試source是否存在,比如創建mappingsd 使用禁用了_source將不會存原文檔(會有這樣一種場景比如source很大,我們
只需要檢索,找到id,然後到hbase等其他數據源中再取具體內容))
18,GET twitter/_doc/2?routing=user1 存儲和獲取的時候可以指定路由字段,如果不指定路由字段默認會到所有分片查,然後聚合查詢結果,如果指定了
路由字段只會查一個分片就行了,默認是 id做爲路由。(如果mapping 中設置了_routing 再用id去查 比如GET twitter/_doc/2 就會出錯,說沒指定路由,id比較特殊?如果
GET twitter/_doc/_search?q=name:zhangsan 就可以,會查所有 分片,id字段特殊性的原因是啥?是由於在mapping 中設置了_routing 字段所以纔會報錯,如果不設置
的話就不會報錯,但由於新增的時候指定了routing 根據id查詢的時候不指定routing 會默認還按id routing,所以會找不到,所以根據id查的時候要強制指定routing)
也就是說如果maping 中設置了_routing 那麼添加和按id查找的時候,就要指定routing,如果maping中沒有設置 routing的話,單添加的時候指定了routing,按id
查找的時候,沒有指定maping,那就會默認按id 路由,由於和添加的時候指定的路由不一致,會找不到,如果不按id查找,也不指定routing 就會到所有分片
上查結果,然後在聚合返回。如果不按id查找,但指定了routing,就只會到一個分片上去查,如果是添加的話,且mapping中設置了 routing ,那麼添加也要帶上
路由字段,否則會報錯,查詢不受影響 mapping 中的_routing 主要是爲了防止添加的時候漏加routing,(see https://blog.csdn.net/u010454030/article/details/73554652/)
"mappings": {
"user1": {
"_routing": {
"required": true
},
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
},
"date": {
"type": "date",
"index": false
}
}
}
}
19,GET /test_service1/user1/5?refresh=true (refresh設置爲true 可以在查詢前先刷新,注意,使用這個參數時,看看是否會造成系統負擔)
20,分片查詢 GET /test_service1/user1/1?version=4&preference=_primary (指定只在主分片中查詢,7.0中廢棄只能用 [_only_nodes] or [_prefer_nodes])
如:GET /test_service1/user1/1?version=4&preference=_only_nodes:node-1 在節點名爲node-1的節點中查詢
二:
1:es的數據類型
1,string,string 類型包含兩種,text,和keyword,text 類型用來索引長文本,會進行分詞,
而keyword,不會進行分詞,keyword類型字段只能用本身來進行檢索。
2,long,integer,short,byte,double,float,boolean,binary(二進制) 就是,如果我們給定的值是 true或false會自動檢測成boolean 如果是字符串
會檢測成string 如果是整數,會檢測成 long,如果是小數,會檢測成float
如果是 2018-12-12 會檢測成date
3,數值類型不會進行分詞,二字符串類型默認會進行分詞,可以通過
GET /test_index1/user1/_mapping 來查看mapping信息,
2:主分片,一旦確定,沒法修改,replicas 可以修改
三:管理
1, 查看集羣健康狀況
GET _cat/health
2,當集羣中增加節點時,如果有replica 沒創建,es 會自動創建