當前位置:首頁 » 數據倉庫 » es更新資料庫
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

es更新資料庫

發布時間: 2022-05-02 14:52:06

1. ES的java API在更新數據時,有沒有方法根據指定欄位更新

兩表根據兩個欄位關聯即可
如 select distinct b.type_name from news a,news_type b where a.news_type_id= b.type_id and a.news_type_id = '1'

2. es 更新後讀寫不一致

系統出現問題。解決方法:
1、開一張表專門記錄創建和更新ES數據不一致的信息(比如我們項目中主需要記錄主表ID,更新數據時根據ID組裝數據),然後設置一個定時任務,定時向ES更新失敗的數據。
2、小批量、多批次更新;通俗講就是設置固定時間間隔,然後更新先前一段時間的數據,比如每隔10分鍾,全量更新前20分鍾的數據;缺點就是有些數據正常的數據也更新了。

3. ES資料庫數據遷移問題

import re
import fileinput

def this_line_is_useless(line):
useless_es = [
'BEGIN TRANSACTION',
'COMMIT',
'sqlite_sequence',
'CREATE UNIQUE INDEX',
]
for useless in useless_es:
if re.search(useless, line):
return True

def has_primary_key(line):
return bool(re.search(r'PRIMARY KEY', line))

searching_for_end = False
for line in fileinput.input():
if this_line_is_useless(line): continue

if re.match(r".*, ''\);", line):
line = re.sub(r"''\);""''\);", r'``);', line)
if re.match(r'^CREATE TABLE.*', line):
searching_for_end = True

4. es導入數據,數據變少

分析
現在導致數據被刪除的情況應該是a表和b表的主鍵id重復,es默認mysql中的 id 為主鍵 並且document 的_id 和id保持一致, 導致a表中的數據被刪除掉了(替換掉了)

三、解決方案
新建一個欄位保存資料庫的id 主鍵數據, 查詢的時候使用uuid作為id的數據
注意
es2.0以後就不支持修改_id映射為其他欄位了,es也不支持聯合主鍵之類的。

5. elasticsearch為什麼從2.x直接更新到5.x

為了ELK(ElasticSearch, logstash, kibana)技術棧的版本統一,免的給用戶帶來混亂。

6. es資料庫鎖死

回答如下:
ES默認實現樂觀鎖,所有的數據更新默認使用樂觀鎖機制。document更新時,必須要帶上currenct version,更新時與document的version進行比較,如果相同進行更新操作,不相同表示已經被別的線程更新過了,此時更新失敗,並且重新獲取新的version再嘗試更新。

7. ElasticSearch這個可以實時的從mysql數據源中更新數據嗎

ElasticSearch這個可以實時的從mysql數據源中更新數據嗎
使用Elasticsearch存儲的文檔數量接近50億(算上1份復制,接近 100億文檔),總共10個數據節點和2個元數據節點(48GB內存,8核心CPU,ES使用內存達到70%),每天的文檔增量大概是3000W條(速度 持續增加中)。

8. ES與傳統資料庫的比較

1.結構名稱不同
2.ES分布式搜索,傳統資料庫遍歷式搜索
3.ES採用倒排索引,傳統資料庫採用B+樹索引
4.ES沒有用戶驗證和許可權控制
5.ES沒有事務的概念,不支持回滾,誤刪不能恢復
6.ES免費,完全開源;傳統資料庫部分免費
有關更詳細的比較內容,可以到黑馬程序員官網找到社區技術文章,找不到可以對話框問一下。裡面還有結合工作的舉例。

9. 如何使用Elasticsearch groovy script腳本更新數據

今天細說一下elasticsearch的update更新功能,以及如何利用script腳本更新數據。

想要使用script腳本功能,需要在配置文件elasticsearch.yml里設置

Python

script.disable_dynamic: false

關於elasticsearch script的文章,總是會沒完沒了的修改

ES支持更新,但是更新的方式是通過一個提供的腳本進行的。ES的做法是,通過
index找到相應的存放記錄的節點,然後執行腳本,執行完之後,返回新的索引。實際上執行的是一個get和reindex的過程,在這個過程中,通過
versioning來控制沒有其它的更新操作(這個功能是0.19後可用的)。具體實現的原理應該和elasticsearch
Versioning相關。

get,reindex的含義是,ES先取出這條記錄,然後根據新數據生成新記錄,然後在把新記錄放回到ES中(並不會覆蓋老的記錄)。

現在沒有數據,首先我們需要創建一條記錄

Python

$ curl -XPUT localhost:9200/xiaorui.cc/blog/1 -d '{
"counter" : 1,
"tags" : ["red"]
}'

$ curl -XPUT localhost:9200/xiaorui.cc/blog/1 -d '{
"counter" : 1,
"tags" : ["red"]
}'

直接修改數據,一定要注意,直接update的化,會覆蓋以前的數據,另外update的時候,需要/index/type/id ,一定要帶著id。 elasticsearch 應該不支持搜索query方式update修改數據。

Python

curl -XPUT 'localhost:9200/xiaorui.cc/blog/1?pretty' -d '
{
"name": "xiaorui.cc"
}'

curl -XPUT 'localhost:9200/xiaorui.cc/blog/1?pretty' -d '
{
"name": "xiaorui.cc"
}'

elasticsearch提供了doc這個局部更新參數,他可以局部修改,而不會直接覆蓋以前的數據,這會針對特定的k v,欄位修改。

Python

curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update?pretty' -d '
{
"doc": { "name": "ruifengyun" }
}'

curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update?pretty' -d '
{
"doc": { "name": "ruifengyun" }
}'

當Elasticsearch API不能滿足要求時,Elasticsearch允許你使用腳本實現自己的邏輯。腳本支持非常多的API,例如搜索、排序、聚合和文檔更新。腳本可以通過請求的一部分、檢索特殊的.scripts索引或者從磁碟載入方式執行。

下面是es script的用法,這些腳本是groovy開發的。 下面的語句的意思是說,將counter的值加4

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
}
}'

通過上面的例子,我們知道tags是個列表,如果用doc局部更新的語法,他是無法做到append的,還是會覆蓋tags這個欄位。 那麼怎麼實現列表擴展? 請使用elasticsearch script實現。

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.tags += tag",
"params" : {
"tag" : "white"
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.tags += tag",
"params" : {
"tag" : "white"
}
}'

_update也支持upsert功能,沒有這個欄位或者key,也會添加這個記錄。下面是一個例子,如果沒有counter欄位,則插入該欄位:

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
},
"upsert" : {
"counter" : 1
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
},
"upsert" : {
"counter" : 1
}
}'

下面我們來復雜點的groovy script腳本用法. 當你的source沒有china這個key,那麼我會增加一個kv

Python

curl -XPOST "http://localhost:9200/xiaorui.cc/blog/80/_update" -d'
{
"script": "if (!ctx._source.containsKey(\"china\")) { ctx._source.attending = newField }",
"params" : {"newField" : "blue" },
"myfield": "data"
}'

curl -XPOST "http://localhost:9200/xiaorui.cc/blog/80/_update" -d'
{
"script": "if (!ctx._source.containsKey(\"china\")) { ctx._source.attending = newField }",
"params" : {"newField" : "blue" },
"myfield": "data"
}'

下面的script語法相對復雜的,會遍歷一組字典,然後進行判斷賦值。

{
「55555″: 22,
「name」: 「lisi」,
「distr_pan」: [
{
「k」: 15,
「v」: 15
},
{
「k」: 20,
「v」: 20
}
]
}

Python

$ curl -XPUT 'localhost:9200/xiaorui.cc/blog/9123/_update' -d '
{
"script" : "def x = false;ctx._source.distr_pan.each({if(it.get('k')==target){x=true}});if(x){ctx._source.distr_pan +=v}",
"params":{
"v":{"k":nlp, "v":35},
"target":15
}
}

$ curl -XPUT 'localhost:9200/xiaorui.cc/blog/9123/_update' -d '
{
"script" : "def x = false;ctx._source.distr_pan.each({if(it.get('k')==target){x=true}});if(x){ctx._source.distr_pan +=v}",
"params":{
"v":{"k":nlp, "v":35},
"target":15
}
}

elasticsearch script就講解到這里了,很多例子已經簡單明了…
script貌似不是很安全,最少遠程代碼執行的漏洞暴露過幾次了. 下次把python版的script走一遍試試.
貌似對於我們你者來說,不管是groovy python,沒什麼太大卻別,語法看起來都一個模子。

10. elasticsearch 怎麼更新數據的

我們經常有這樣的需求,在對 Elasticsearch 數據進行操作的時候,要及時返回剛剛操作完畢的數據,或者數據列表。

比如加入存儲一條數據後,我馬上要返回數據的總條數,這個時候,會出問題,Elasticsearch會返回操作之前的數據,也就是假如開始有500條數據,我Insert了一條進去,按道理來說應該是501條,但是這個時候查詢會發現,只有500條數據,再次請求又得到501條數據,這個是怎麼回事呢?

這個問題因為 Elasticsearch 有延遲的關系(好像記得是3秒還是1秒來著)。有的人的做法比如有以下方法解決的。

Thread.sleep(3000L);
還有再請求一次的。但這些都不是解決方案,當你知道有方法的時候,你會自己笑自己。

其實我看過這個網站的博客里有用到,但是群主沒提到這個方法的作用。

在:http://www.sojson.com/blog/88.html里有一句代碼,如下:

BulkRequestBuilder bulkRequest = ESTools.client.prepareBulk().setRefresh(true);
這里的setRefresh(true);

就是自動刷新的用處。所以在我們CRUD的時候,如果對數據增刪改操作的時候,如果要及時返回最新數據,那麼我們就需要加這個方法,及時刷新數據。
當然 Elasticsearch 也是可以配置刷新時間的,但是沒必要,頻繁的刷新會造成壓力過大。