es 常用操作

一:索引相關

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 會自動創建

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章