[原創] RavenDB 安裝 使用
RavenDB 安裝/使用
文件極少, 幾乎沒有社群討論, 官網對 HTTP API 的文件幾乎沒有. (版本2.5有一些 HTTP API 文件).
SDK 示例程式碼以 c# 為主, 其餘幾乎為空.
文中測試的 API 都是在瀏覽器 UI 上操作抓包獲取. 有些 API 是靠感覺猜出來的.
到底還是.net寫的 … 安裝目錄就一個 Server 資料夾, 裡面放著所有的 .dll, .so, *.json …
和 couchdb 相比, 易用性好一些. 但從整體上看, 不如 couchdb.
下載/安裝
下載地址: https://ravendb.net/download
支援: WINDOWS, LINUX, MACOS, RASPBERRY PI, DOCKER, NUGET
這裡是在 Macbook 上安裝的
$ wget https://daily-builds.s3.amazonaws.com/RavenDB-4.0.2-osx-x64.tar.bz2
$ tar zxvf RavenDB-4.0.2-osx-x64.tar.bz2
$ cd RavernDB
$ bash run.sh
# 需要安裝 libsodium 模組
# brew install libsodium
啟動/配置
可以看到啟動成功. 預設埠是5984
# 如果沒有異常, 會看到如下提示
Using GC in server concurrent mode retaining memory from the OS.
Could not start browser: No such file or directory
Server available on: http://127.0 .0.1:57606
Tcp listening on 127.0.0.1:57607
Server started, listening to requests...
TIP: type 'help' to list the available commands.
Running non-interactive.
$ curl -v http://127.0.0.1:57606
* Rebuilt URL to: http://127.0.0.1:57606/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 57606 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:57606
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Tue, 10 Apr 2018 09:12:44 GMT
< Content-Type: application/json; charset=utf-8
< Server: Kestrel
< Content-Length: 0
< Location: /studio/index.html
<
* Connection #0 to host 127.0.0.1 left intact
直接開啟瀏覽器, 訪問控制檯提示的地址, 會引導進行一些配置, 安全配置等等資訊.
在安裝目錄 Server 中,有一個 setting.json, 預設如下
{
"ServerUrl": "http://127.0.0.1:0",
"Setup.Mode": "Initial",
"DataDir": "RavenData"
}
可以替換為如下, 略過引導配置
{
"DataDir": "RavenData",
"License.Eula.Accepted": true,
"Setup.Mode": "Unsecured",
"Security.UnsecuredAccessAllowed": "PublicNetwork",
"ServerUrl": "http://127.0.0.1:8080",
"ServerUrl.Tcp": "tcp://127.0.0.1:38888"
}
ServerUrl 監聽 http 請求
DataDir 配置資料檔案目錄
Setup.Mode 啟動模式
ServerUrl.Tcp 是用於叢集模式節點之間通訊. - Indicates the IP addresses or host addresses with ports and protocols that the server should listen on for incoming TCP connections, are used for inter-node communication
使用測試
測試可以使用瀏覽器直接測試, 這裡不做說明
使用 curl 測試
建立 DB
$ curl -X PUT "http://127.0.0.1:8080/admin/databases?name=td&replicationFactor=1" -d '{"DatabaseName":"td"}'
{
"RaftCommandIndex": 19,
"Name": "td",
"Topology": {
"Members": [
"A"
],
"Promotables": [],
"Rehabs": [],
"Stamp": {
"Index": -1,
"Term": 1,
"LeadersTicks": 113011146
},
"PromotablesStatus": {},
"DemotionReasons": {},
"DynamicNodesDistribution": false,
"ReplicationFactor": 1
},
"NodesAddedTo": [
"http://127.0.0.1:8080"
]
}
$ curl -X PUT "http://127.0.0.1:8080/admin/databases?name=td&replicationFactor=1" -d '{
"DatabaseName": "td",
"Settings": {
"DataDir": null
},
"Disabled": false,
"Encrypted": false,
"Topology": {
"DynamicNodesDistribution": false
}
}'
{"Url":"/admin/databases?name=td&replicationFactor=1","Type":"Raven.Client.Exceptions.ConcurrencyException","Message":"Database 'td' already exists!","Error":"Raven.Client.Exceptions.ConcurrencyException: Database 'td' already exists!\n at Raven.Server.Web.System.AdminDatabasesHandler.<CreateDatabase>d__6.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Web\\System\\AdminDatabasesHandler.cs:line 326\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Raven.Server.Web.System.AdminDatabasesHandler.<Put>d__4.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Web\\System\\AdminDatabasesHandler.cs:line 233\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Raven.Server.Routing.RequestRouter.<HandlePath>d__6.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Routing\\RequestRouter.cs:line 104\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\n at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()\n at Raven.Server.RavenServerStartup.<RequestHandler>d__11.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\RavenServerStartup.cs:line 159"}
支援 revision
# 檢視當前資料庫配置的 revision
$ curl http://127.0.0.1:8080/databases/qa/revisions/config
{
"Default": null,
"Collections": {
"@empty": {
"Disabled": false,
"MinimumRevisionsToKeep": null,
"MinimumRevisionAgeToKeep": null,
"PurgeOnDelete": false
}
}
}
# 配置 revision
curl -XPOST http://127.0.0.1:8080/databases/qa/admin/revisions/config -d '{
"Collections": {
"@empty": {
"Disabled": false,
"MinimumRevisionsToKeep": 100,
"MinimumRevisionAgeToKeep": null,
"PurgeOnDelete": false
}
}
}'
{"RaftCommandIndex":21}
Disabled, true: 關閉 revision, false: 開啟 revision.
MinimumRevisionsToKeep: 保留最近多少個版本, 可以設定為 null
MinimumRevisionAgeToKeep: 保留最近多少天的版本, 可以設定為 null
PurgeOnDelete: 刪除的時候是否徹底清除. 建議 false新增記錄時, 如果不指定
@[email protected]
, 會預設新增到@empty
collection
RavenDB 預設不支援 revision, 需要手動開啟. revision 作用域是某個 database 中的 collection特別注意: 配置 revision 時, 會覆蓋原先的設定, 所以每次提交都必須將以前設定的 revision 也新增進去. 否則會丟失原先的配置.
新增一條記錄 (_id 可以自己定義, 也可以不填, 會預設生成 GUID)
$ curl -XPUT "http://127.0.0.1:8080/databases/qa/docs?id=1" -d '{"name": "zhipeng"}'
{"Id":"1","ChangeVector":"A:22-5YM16pKww0W6G+UxDC7ViQ"}
$ curl -XPUT "http://127.0.0.1:8080/databases/qa/docs?id=2" -d '{
"name": "zhipeng",
"@metadata": {},
"books":["aa", "bb"],
"school": [{"type": "h", "name": "high school"}, {"type": "u", "name": "university"}],
"other": {"age": 18, "first_name": "zhang"},
"desc": "hello world."
}'
{"Id":"2","ChangeVector":"A:42-5YM16pKww0W6G+UxDC7ViQ"}
# 也可以使用 bulk 操作
# 插入一條 id 為2的, 裡面包含 list, dictionary 兩種型別. ["", ""], [{}, {}], {}
$ curl -XPOST http://127.0.0.1:8080/databases/qa/bulk_docs -d '{
"Commands": [
{
"Document": {
"info": {
"a": 123,
"b": 456
},
"name": "zhipeng",
"@metadata": {
"@collection": "qa",
"@id": ""
}
},
"Id": "",
"Type": "PUT"
},
{
"Document": {
"name": "zhipeng",
"books": [
"aa",
"bb"
],
"school": [
{
"type": "h",
"name": "high school"
},
{
"type": "u",
"name": "university"
}
],
"other": {
"age": 18,
"first_name": "zhang"
},
"desc": "hello world.",
"@metadata": {
"@id": "2"
}
},
"Id": "2",
"Type": "PUT"
}
]
}'
{
"Results": [
{
"Type": "PUT",
"@id": "2",
"@collection": "@empty",
"@change-vector": "A:42-5YM16pKww0W6G+UxDC7ViQ",
"@last-modified": "2018-04-10T11:41:17.1278590",
"@flags": "HasRevisions"
},
{
"Type": "PUT",
"@id": "269639cf-0852-430c-b256-3cdee38b2519",
"@collection": "qa",
"@change-vector": "A:14-5YM16pKww0W6G+UxDC7ViQ",
"@last-modified": "2018-04-10T10:27:33.9939300",
"@flags": "HasRevisions"
}
]
}
$ curl -XPUT "http://127.0.0.1:8080/databases/qa/docs" -d '{"name": "zhipeng"}'
{"Url":"/databases/qa/docs?id=%20","Type":"System.ArgumentException","Message":"Query string value 'id' must have a non empty value","Error":"System.ArgumentException: Query string value 'id' must have a non empty value\n at Raven.Server.Web.RequestHandler.InvalidEmptyValue(String name) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Web\\RequestHandler.cs:line 341\n at Raven.Server.Web.RequestHandler.GetQueryStringValueAndAssertIfSingleAndNotEmpty(String name) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Web\\RequestHandler.cs:line 333\n at Raven.Server.Documents.Handlers.DocumentHandler.<Put>d__7.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\Handlers\\DocumentHandler.cs:line 240\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Raven.Server.Routing.RequestRouter.<HandlePath>d__6.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Routing\\RequestRouter.cs:line 97\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\n at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()\n at Raven.Server.RavenServerStartup.<RequestHandler>d__11.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\RavenServerStartup.cs:line 159"}
如果不使用 bulk, 必須指定 id, 否則無法自動生成 id.
查詢 - 獲取所有記錄
$ curl "http://127.0.0.1:8080/databases/qa/docs?start=0&pageSize=10"
{
"Results": [
{
"name": "zhipeng",
"@metadata": {
"@change-vector": "A:40-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "1",
"@last-modified": "2018-04-10T11:29:39.6150230Z"
}
},
{
"name": "zhipeng",
"desc": "test collection.x'x'x",
"@metadata": {
"@collection": "qa",
"@change-vector": "A:12-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "zhipeng",
"@last-modified": "2018-04-10T09:41:57.0446820Z"
}
}
]
}
# 也可以用這個 API, 可以返回查詢到的資料所包含的欄位
curl "http://127.0.0.1:8080/databases/qa/studio/collections/preview?start=0&pageSize=10"
{
"Results": [
{
"@metadata": {
"$a": [],
"$o": [],
"$t": [],
"@change-vector": "A:40-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "1",
"@last-modified": "2018-04-10T11:29:39.6150230Z"
}
},
{
"@metadata": {
"$a": [],
"$o": [],
"$t": [],
"@collection": "qa",
"@change-vector": "A:12-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "zhipeng",
"@last-modified": "2018-04-10T09:41:57.0446820Z"
}
}
],
"TotalResults": 2,
"AvailableColumns": [
"name",
"desc"
]
}
查詢 - 根據 id 查詢
$ curl "http://127.0.0.1:8080/databases/qa/docs?id=1"
{
"Results": [
{
"name": "zhipeng",
"@metadata": {
"@change-vector": "A:40-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "1",
"@last-modified": "2018-04-10T11:29:39.6150230Z"
}
}
],
"Includes": {}
}
$ curl "http://127.0.0.1:8080/databases/qa/docs?id=2&id=1"
{
"Results": [
{
"name": "zhipeng",
"books": [
"aa",
"bb"
],
"school": [
{
"type": "h",
"name": "high school"
},
{
"type": "u",
"name": "university"
}
],
"other": {
"age": 18,
"first_name": "zhang"
},
"desc": "hello world.",
"@metadata": {
"@change-vector": "A:42-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "2",
"@last-modified": "2018-04-10T11:41:17.1278590Z"
}
},
{
"name": "zhipeng",
"@metadata": {
"@change-vector": "A:40-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "1",
"@last-modified": "2018-04-10T11:29:39.6150230Z"
}
}
],
"Includes": {}
}
# 等同下面的效果
$ curl -XPOST "http://127.0.0.1:8080/databases/qa/docs" -d '{"Ids":[2,1, "zhipeng"]}'
如果需要查詢多個 id, 可以在引數中拼接. 例如
id=1&id=2
查詢 - 查詢語法
RavenDB 將 SQL 稱之為 RQL. 後面 RQL 都用 SQL 表示.
查詢地址: /databases/qa/queries?query=SQL&start=0&pageSize=10
平常的 SQL 是 select fields from TABLE where WHERE\_SYNTAX;
RavenDB SQL 稍有不同, 是 from TABLE where WHERE\_SYNTAX select fields
注意行尾不要加
;
$ curl "http://127.0.0.1:8080/databases/qa/queries?query=from%20qa%20%20%0D%0Awhere%20name%20%3D%20%22zhipeng%22%0D%0Aselect%20ID()%20as%20id%2C%20name&start=0&pageSize=10"
{
"TotalResults": 2,
"SkippedResults": 0,
"DurationInMs": 0,
"IncludedPaths": null,
"IndexName": "Auto/qa/Bybooks.CountAndbooks[]AndnameAndother.ageAndschool[].type",
"Results": [
{
"id": "zhipeng",
"name": "zhipeng",
"@metadata": {
"@projection": true,
"@change-vector": "A:12-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "zhipeng",
"@index-score": 0.594534814357758,
"@last-modified": "2018-04-10T09:41:57.0446820Z"
}
},
{
"id": "2",
"name": "zhipeng",
"@metadata": {
"@projection": true,
"@change-vector": "A:52-5YM16pKww0W6G+UxDC7ViQ",
"@id": "2",
"@index-score": 0.594534814357758,
"@last-modified": "2018-04-11T03:04:48.1657180Z"
}
}
],
"Includes": {},
"IndexTimestamp": "2018-04-11T04:06:00.7646740",
"LastQueryTime": "2018-04-11T04:17:41.3646580",
"IsStale": false,
"ResultEtag": -6847100035392847000
}
後面只寫 SQL, 不再寫 curl, 將 SQL 用 urlEncode 後放入引數 query 即可
基礎查詢
from qa where name = "zhipeng" select ID() as id, name
from qa group by name where name = "zhipeng" select name, count() as count
需要注意, 不能直接使用如果要使用
COUNT()
, 必須使用聚合函式.
主鍵 id 必須使用ID()
才可以正常返回. 否則只能從 @metadata 中獲取
list 相關查詢
from qa where books.Count = 2 select books, ID() as ID
// 這裡是可以使用一部分 js 語法的
from qa where books.length = 2 select books, ID() as ID
SQL: from qa as c where c.books.length = 2 select { book: c.books, metadata: c["@metadata"], _source: c, id: c["@metadata"]["@id"]}
// 查詢 books 中存在 "aa" 這本書的所有記錄
from qa where books[] = "aa" select *
//result
{
"TotalResults": 1,
"SkippedResults": 0,
"DurationInMs": 0,
"IncludedPaths": null,
"IndexName": "Auto/qa/Bybooks.CountAndbooks[]",
"Results": [
{
"name": "zhipeng",
"books": [
"aa",
"bb"
],
"school": [
{
"type": "h",
"name": "high school"
},
{
"type": "u",
"name": "university"
}
],
"other": {
"age": 18,
"first_name": "zhang"
},
"desc": "hello world.",
"@metadata": {
"@collection": "qa",
"@change-vector": "A:52-5YM16pKww0W6G+UxDC7ViQ",
"@id": "2",
"@index-score": 0.3068528175354,
"@last-modified": "2018-04-11T03:04:48.1657180Z"
}
}
],
"Includes": {},
"IndexTimestamp": "2018-04-11T03:45:00.7649240",
"LastQueryTime": "2018-04-11T03:59:53.3999770",
"IsStale": false,
"ResultEtag": 3604079527690140700
}
dictionary 查詢
from qa where other.age=18 select ID() as id, name, other.age as age
// 查詢上過高中的人名
from qa where school.type = 'h' select name
需要注意, 如果使用 js 語法查詢, 是沒有辦法獲取到 id 的, 從能後續從@ metadata 中獲取. 不知道是 bug 還是原因. 如果直接獲取這行記錄, 是可以看到@[email protected] 的, 但如果直接獲取[“@metadata”]只能看到@ collection. 所以 id 也就無法獲取.
並且試了 load 語法, 似乎也不行, 獲取不到結果. 可能是 bug 吧, 用不到這個, 所以不細研究了.
from qa as q
load q.other as o
select {
name: q.name.toUpperCase(),
other: o.age,
bookCount: q.books.length
}
// result
{
"TotalResults": 2,
"SkippedResults": 0,
"DurationInMs": 0,
"IncludedPaths": null,
"IndexName": "collection/qa",
"Results": [
{
"name": "ZHIPENG",
"other": null,
"bookCount": null,
"q": {
"@collection": "qa"
},
"@metadata": {
"@projection": true,
"@change-vector": "A:12-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions",
"@id": "zhipeng",
"@index-score": 0,
"@last-modified": "2018-04-10T09:41:57.0446820Z"
}
},
{
"name": "ZHIPENG",
"other": null,
"bookCount": 2,
"q": {
"@collection": "qa"
},
"@metadata": {
"@projection": true,
"@change-vector": "A:52-5YM16pKww0W6G+UxDC7ViQ",
"@id": "2",
"@index-score": 0,
"@last-modified": "2018-04-11T03:04:48.1657180Z"
}
}
],
"Includes": {},
"IndexTimestamp": "0001-01-01T00:00:00.0000000",
"LastQueryTime": "0001-01-01T00:00:00.0000000",
"IsStale": false,
"ResultEtag": 6893458203660772000
}
更新
更新記錄和插入記錄介面一樣, 已存在的記錄會自己做版本管理
更新的時候, @metadata 和原記錄保持一致. @collection 不可以更改.
刪除
$ curl -XDELETE "http://127.0.0.1:8080/databases/qa/docs?id=1"
# 也可以使用 bulk 進行批量刪除,
$ curl -X POST http://127.0.0.1:8080/databases/qa/bulk_docs -d '{"Commands":[{"Id":"0910b0f3-3878-4667-811f-3c0cff067f44","Type":"DELETE"},{"Id":"269639cf-0852-430c-b256-3cdee38b2519","Type":"DELETE"}]}'
{
"Results": [
{
"Id": "0910b0f3-3878-4667-811f-3c0cff067f44",
"Type": "DELETE",
"Deleted": true
},
{
"Id": "269639cf-0852-430c-b256-3cdee38b2519",
"Type": "DELETE",
"Deleted": true
}
]
}
刪除的時候不需要指定版本號, couchdb 必須指定.
刪除只是刪除當前版本, 並且會生成出一個被刪除的版本. 舊版本是可以繼續查到的.
如果再建立一條記錄,_id
存在過, 版本號會在最後一次刪除的版本基礎上 +1.
檢視版本記錄
$ curl "http://127.0.0.1:8080/databases/qa/revisions?id=1&start=0&pageSize=100&metadataOnly=false"
{
"Results": [
{
"name": "11",
"desc": "1",
"@metadata": {
"@collection": "qa",
"@change-vector": "A:58-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions, Revision",
"@id": "1",
"@last-modified": "2018-04-11T06:50:46.7506050Z"
}
},
{
"@metadata": {
"@collection": "@empty",
"@change-vector": "A:53-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions, DeleteRevision",
"@id": "1",
"@last-modified": "2018-04-11T06:48:46.4398030Z"
}
},
{
"Name": "...",
"@metadata": {
"@change-vector": "A:36-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions, Revision",
"@id": "1",
"@last-modified": "2018-04-10T10:45:11.6156140Z"
}
},
{
"name": "zhipeng",
"id": "1",
"@metadata": {
"@change-vector": "A:16-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions, Revision",
"@id": "1",
"@last-modified": "2018-04-10T10:36:22.3838210Z"
}
}
],
"TotalResults": 11
}
metadataOnly=true
只返回 metadata 資訊. 預設為 false
檢視某個版本記錄
$ curl "http://127.0.0.1:8080/databases/qa/revisions?changeVector=A%3A58-5YM16pKww0W6G%2BUxDC7ViQ"
{
"Results": [
{
"name": "11",
"desc": "1",
"@metadata": {
"@collection": "qa",
"@change-vector": "A:58-5YM16pKww0W6G+UxDC7ViQ",
"@flags": "HasRevisions, Revision",
"@id": "1",
"@last-modified": "2018-04-11T06:50:46.7506050Z"
}
}
]
}
檢視某條記錄的某個版本, 只需要用 @change-vector 即可, 不需要 id.
特別注意, 某條記錄如果已經設定了 collection, 是不能再更換 collection 的. 即使第一次是 @empty, 也不能更換.如果想更換 collection, 只能將其刪除, 重新建立, 並指定 collection.
切換過 collection 的資料, 短時間內不能再刪除, 只能更新. 比如上面id=1
的 revision, collection 就是從 @empty 切換到 qa, 繼續操作刪除, 就會報錯.
$ curl POST http://127.0.0.1:8080/databases/qa/bulk_docs -d '{"Commands":[{"Id":"1","Type":"DELETE","ChangeVector":null}]}'
$ curl -v -XDELETE "http://127.0.0.1:8080/databases/qa/docs?id=1"
Voron.Exceptions.ConcurrencyException: Value already exists, but requested NewOnly
{"Url":"/databases/qa/bulk_docs","Type":"Voron.Exceptions.ConcurrencyException","Message":"Value already exists, but requested NewOnly","Error":"Voron.Exceptions.ConcurrencyException: Value already exists, but requested NewOnly\n at Voron.Data.BTrees.Tree.ThrowConcurrencyException() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Voron\\Data\\BTrees\\Tree.cs:line 411\n at Voron.Data.BTrees.Tree.DirectAdd(Slice key, Int32 len, TreeNodeFlags nodeType, Byte*& ptr) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Voron\\Data\\BTrees\\Tree.cs:line 292\n at Voron.Data.Tables.Table.InsertIndexValuesFor(Int64 id, TableValueReader& value) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Voron\\Data\\Tables\\Table.cs:line 611\n at Voron.Data.Tables.Table.Insert(TableValueBuilder builder) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Voron\\Data\\Tables\\Table.cs:line 479\n at Raven.Server.Documents.DocumentsStorage.CreateTombstone(DocumentsOperationContext context, Slice lowerId, Int64 documentEtag, CollectionName collectionName, String docChangeVector, Int64 lastModifiedTicks, String changeVector, DocumentFlags flags) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\DocumentsStorage.cs:line 1320\n at Raven.Server.Documents.DocumentsStorage.Delete(DocumentsOperationContext context, Slice lowerId, String id, LazyStringValue expectedChangeVector, Nullable`1 lastModifiedTicks, String changeVector, CollectionName collectionName, NonPersistentDocumentFlags nonPersistentFlags, DocumentFlags documentFlags) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\DocumentsStorage.cs:line 1129\n at Raven.Server.Documents.DocumentsStorage.Delete(DocumentsOperationContext context, String id, String expectedChangeVector) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\DocumentsStorage.cs:line 1028\n at Raven.Server.Documents.Handlers.BatchHandler.MergedBatchCommand.Execute(DocumentsOperationContext context) in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\Handlers\\BatchHandler.cs:line 305\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at Raven.Server.Documents.Handlers.BatchHandler.<BulkDocs>d__0.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Documents\\Handlers\\BatchHandler.cs:line 59\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at Raven.Server.Routing.RequestRouter.<HandlePath>d__6.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\Routing\\RequestRouter.cs:line 97\n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\n at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()\n at Raven.Server.RavenServerStartup.<RequestHandler>d__11.MoveNext() in C:\\Builds\\RavenDB-Stable-4.0\\src\\Raven.Server\\RavenServerStartup.cs:line 159"}
大概2分鐘左右, 就可以刪除成功. 應該是資料同步有一定延時造成的.
通過這個現象, 我認為 RavenDB collection 不等同於 mongodb 中的 collection, mongodb 中的 collection 可以理解為傳統資料庫中的 table, 但 RavenDB 中, 應該將 database 理解為表.
參考
相關推薦
[原創] RavenDB 安裝 使用
RavenDB 安裝/使用 文件極少, 幾乎沒有社群討論, 官網對 HTTP API 的文件幾乎沒有. (版本2.5有一些 HTTP API 文件). SDK 示例程式碼以 c# 為主, 其餘幾乎為空. 文中測試的 API 都是在瀏覽器 UI 上操作抓
[原創]OpenvSwitch安裝
源碼編譯 bit 數據庫 sch private usr ger 模式 linu 一、安裝環境: ubuntu-12.04-64bit 二、使用root權限,安裝所需軟件: apt-get install build-essential apt-get install op
[原創]mininet安裝
運行 源碼安裝 shark pin nap 默認 12.1 director reference mininet安裝: on Ubuntu 13.04: sudo apt-get install minineton Ubuntu 12.10: sudo apt-get in
[原創]CentOS7安裝遠程工具teamviewer12
圖片 processor .rpm rpm clas pass ces 環境 重置密碼 系統環境:CentOS 7.0.1 1.下載安裝# wget https://dl.tvcdn.de/download/version_12x/teamviewer_12.0.85001
[原創]macOS安裝wget
mac用了一年多,今天使用wget命令,竟然提示命令不存在。只好下載原始碼進行安裝了。 安裝過程有點曲折: 編譯wget時,提示pkg-config不存在 第一次從git上下載了pkg-config的原始碼,雖然注意到檔名為pkg-config-pkg-config-0.29.2.tar.gz,而
【原創】安裝ODAC後,PL/SQL連線提…
問題描述: 安裝ODAC後,用PL/SQL登入測試原有的資料庫,先是提示:access violation ataddress....,重啟監聽後又 提示“TNS:無法解析指定的連線識別符號”錯誤。 原因分析: 因為同事也裝過一次,說是不能與oracle客戶端裝在同一個目錄下。但
【原創 Spark動手實踐 1】Hadoop2.7.3安裝部署實際動手
dmi 遠程 nag proc host 一個 error img 連接 目錄: 第一部分:操作系統準備工作: 1. 安裝部署CentOS7.3 1611 2. CentOS7軟件安裝(net-tools, wget, vim等) 3. 更新CentOS
[原創]MacPro上使用VMware Fusion安裝CentOS7 minimal版
x86_64 什麽 mdk cnblogs art 連接 安裝過程 普通用戶 大小 MacPro上使用VMware Fusion安裝CentOS7 minimal版 版權聲明:本文為博主原創文章,轉載請註明出處。 一.系統環境 macPro: VMware Fu
【原創】使用workstation安裝Xenserver 6.5+cloudstack 4.10----本地存儲模式
登錄 queue alt ast rim 4.0 個人學習 white 配置 1. 背景: 近期由於項目和個人學習得需求,開始接觸到Cloudstack,雖然雲計算概念在大學剛畢業的時候就已經略有耳聞,但是由於工作原因,也一直沒有了解,下班後想自己折騰下cloudstac
[原創]在Centos7.2上源碼安裝PHP、Nginx、Zentao禪道
session zip nss markdown src roo -perm mbstring 復制 版本 操作系統:CentOS Linux release 7.2.1511 (Core) PHP:5.6.33 Nginx:1.12.2 MySQL:5.6.38(192
Jetson TX2安裝固態硬盤(原創)
src dia image mat 查看系統 orm alt ron ets SSD on Jetson TX2 註意事項:在斷電情況下,將固態硬盤的接線與Jetson TX2進行連接 步驟: 一、jetson tx2開機,打開搜索欄中的Disks 二、Disks
Linux安裝mysql(Redhat6.5+MySQL5.7)(轉載+原創補漏)
controls 新版 file grep gin leg 下載 set CP 這裏我創建了一目錄software用於存放我們待會要下載的mysql包,先去到該目錄 命令:cd /software命令:wget http://mirrors.sohu.com/mysql/M
(趙強老師原創)搭建CDH實驗環境,三個節點的安裝配置
大數據 CDH 安裝配置 Hadoop Spark 趙強老師簡介-------------------------------------------------------清華大學軟件工程專業畢業。現就職於Oracle(中國)有限公司高級技術顧問,在Oracle公司服務已超過10年。業界
[原創]X-HDL 4.2安裝與使用
由於涉及到VHDL工程,但實際工作中,用Verilog更多些,因此安裝X-HDL進行轉換,安裝步驟與使用如下: X-HDL進行破解,破解如下: 安裝完畢後,開啟一個帶轉換的檔案,進行如下操作: 連結:https://pan.baidu.com/s/
[樂意黎原創]Centos主機動態安裝PHP的bcmath,Libmcrypt,mhash,mcrypt等擴充套件模組方法
如下,Centos裡啟動 php-fpm 時,控制檯總在拋若干警告。 [[email protected]] #service php-fpm start Starting php-fpm daemon is success[28-Nov-2018 17:45:40] NOTIC
最新原創個人實踐總結安裝CocoaPods方法詳解
首先升級Ruby環境,終端輸入:gem update --system,會出現兩種情況, 1,Latest version already installed. Done. 說明已經最新 2,沒許可權升級Ruby的提示,這是因為你沒有許可權去升級Ruby 這時應該輸
zzw原創_非root安裝fastDFS
zzw原創_非root安裝fastDFS fastDFS 想要非root安裝,沒找到資料,分析了一下安裝指令碼,原來作者是留了安裝路徑的,但沒有放出來。 1、解包 [[email protected] setup]$ tar -xvf libfastco
原創Linux Centos6.9 安裝Oracle11G R2
純原創手敲 累吐血。。。。。。,詳情檢視附件rar中的word(內有命令操作截圖) 1. 解除安裝先檢視 rpm -qa | grep java rpm -e --nodeps java-1.4.2-g
VS2005下編譯、安裝Net-snmp 5.4.1.2手記(原創)
VS2005下編譯、安裝Net-snmp 5.4.1.2手記 by Flyfish <[email protected]>2008-09-08:=======================================================
[原創]Homestead 開發環境安裝筆記
Vagrant 安裝 Homestead 筆記 參考文章: 1. 預先準備 命令列 說明 vagrant init 初始化 vagrant vagrant up 啟動 vagrant