CouchDB 簡單HTTP接口使用說明


1、簡介

Apache CouchDB 是一個面向文檔的數據庫管理系統。它提供以 JSON 作為數據格式的 REST 接口來對其進行操作,並可以通過視圖來操縱文檔的組織和呈現。 CouchDB 是 Apache 基金會的頂級開源項目。
CouchDB里面有一個小問題,就是它的一些預定義的key有時候有下划線,有時候又不能有下划線開頭,例如id``rev這樣的。沒有固定下來,不知道是為何。

參考資料:

2、安裝

直接去官網下載對應的安裝包安裝即可。
安裝之后服務會自動啟動,監聽5984(HTTP)和6984(HTTPS)端口,可以直接在瀏覽器訪問http://127.0.0.1:5984/_utils地址,打開Web交互操作頁面。
Your Account頁面創建服務管理員用戶或修改用戶密碼。

2、HTTP接口簡單使用

CounchDB相關文檔可以查閱http://docs.couchdb.org
這里只簡單記錄一下我用到的幾個HTTP接口。

CouchDB HTTP接口返回狀態碼簡述
這里只列出常用的狀態碼及其說明,特定的請求類型不同的狀態碼信息在相應的API參考文檔中有詳細說明。

狀態碼 狀態 說明
200 OK 請求已經成功完成
201 Created 文檔創建成功
202 Accepted 請求已被接受,但相應的操作可能尚未完成。
這用於后台操作,例如數據庫壓縮
304 Not Modified 請求的其他內容尚未修改。這與ETag系統一起使用以識別返回的信息的版本
400 Bad Request 不良請求。該錯誤可能由於請求URL、Path或Header出錯。
提供的MD5值和content不匹配也會觸發此錯誤,因為這可能是消息內容被破壞
401 Unauthorized 使用提供的授權無法獲得所請求的項目,或未提供授權
403 Forbidden 禁止請求的項目或操作
404 Not Found 找不到請求的內容。
返回的content將相關信息,返回的JSON對象包含鍵errorreason(原因)。例如:
{"error":"not_found","reason":"no_db_file"}
405 Method Not Allowed 對請求的URL使用無效的HTTP請求類型發出了請求。
例如,您需要POST時請求PUT。此類型的錯誤也可能由無效的URL字符串觸發。
406 Not Acceptable 服務器不支持請求的內容類型
409 Conflict 請求導致更新沖突
412 Precondition Failed 來自客戶端的請求標頭和服務器的功能不匹配
413 Request Entity Too Large 請求實體太大
415 Unsupported Media Type 不支持的媒體類型
416 Requested Range Not Satisfiable 服務器無法滿足請求頭中指定的范圍
417 Expectation Failed 批量發送文檔時,批量加載操作失敗
201 Internal Server Error 請求無效,原因是提供的JSON無效,或者作為請求的一部分提供了無效信息

2.1、認證接口

認證的方式官網文檔中介紹的有三種,我只對前面兩種進行了操作。具體的可見http://docs.couchdb.org/en/latest/api/server/authn.html

要學習HTTP協議的認證相關內容,可以看Mozilla的文檔,全中文的。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication

2.1.1 Basic Authentication

基本身份驗證Basic authentication (RFC 2617)是一個比較快速方便的認證方式,對於需要認證的接口,每次都要發送用戶憑據。

這個認證方式具體的操作,就是在發送請求的時候,在HTTP頭中添加Authorization消息頭,其內容為Bascic 使用Basic64編碼的賬號:密碼
例如,賬號為user1,密碼為abcd1234的用戶,那么他發送的一個請求的示例如下:
curl命令請求

curl --request GET \
  --url http://localhost:5984/db1/doc1 \
  --header 'authorization: Basic bzphc2QxMjM=' 
}'

請求報文如下:

GET / HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcjE6YWJjZDEyMzQ=
Host: localhost:5984

其中dXNlcjE6YWJjZDEyMzQ=即為user1:abcd1234的Base64編碼值。

cookie身份驗證(RFC 2109),CouchDB會生成一個token(令牌),客戶端可以使用該token(令牌)來處理CouchDB的下一個請求。 token(令牌)在超時前有效。 當CouchDB在后續請求中看到有效token(令牌)時,它將通過此token(令牌)對用戶進行身份驗證,而無需再次請求密碼。 默認情況下,cookie有效期為10分鍾,可以在配置頁面進行修改,也可以使cookie持久化。

具體操作過程如下:
1、獲取token
要獲取一個token(實際就是獲取響應消息頭中的Set-Cookie值),必須將用戶名和密碼發送到CouchDB服務器,這個通過_session接口來實現。
_session接口說明
_session是一個POST請求接口,只需要設置請求消息頭Content-Type參數,其值可以是application/x-www-form-urlencoded或者application/json。請求的content實體內容格式根據Content-Type的值確定。
更多具體的參數請參考官方文檔。
curl命令如下(發送的是json格式的):

curl --request POST \
  --url http://localhost:5984/_session \
  --header 'content-type: application/json' \
  --data '{
	"name":"user1",
	"password":"abcd1234"
}'

報文示例如下:

POST /_session HTTP/1.1
Accept: application/json
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
Host: localhost:5984

name=root&password=relax

使用JSON格式的請求報文示例:

POST /_session HTTP/1.1
Accept: application/json
Content-Length: 37
Content-Type: application/json
Host: localhost:5984

{
    "name": "root",
    "password": "relax"
}

成功返回的響應內容示例如下:

HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 43
Content-Type: application/json
Date: Mon, 03 Dec 2012 01:23:14 GMT
Server: CouchDB (Erlang/OTP)
Set-Cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly

{"ok":true,"name":"root","roles":["_admin"]}

返回的json對象中ok的值表示操作狀態,name的值是用戶名,relos數組中是用戶的角色(一個用戶可以有多個角色)。
響應報文中的Set-Cookie消息頭的值,就是后面所有請求需要使用到的Cookie內容。

返回的狀態碼可能是以下三個

狀態碼 狀態 說明
200 OK 成功通過身份驗證
302 Found 成功驗證后重定向
401 Unathorized 無法識別用戶名或密碼

2、使用token
通過上一步獲取到Cookie值之后,就可以對一些需要認證的接口進行操作。簡單來說,就是在發送請求的時候添加Cookie消息頭。
curl命令示例

curl --request GET \
  --url http://localhost:5984/db1 \
  --header 'cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw
# 或將上面的--header不要,改為使用下面的參數
#  --cookie 'AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw'

3、刪除token
刪除一個token即表示這個Cookie不再使用了,也就是關閉這個會話。但因為CouchDB Cookie是無狀態的,所以此操作實際並不起什么作用。
刪除使用一個DELETE請求,curl命令示例如下:

curl --request DELETE \
  --url http://localhost:5984/_session \
  --header 'cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw;

請求報文示例如下:

DELETE /_session HTTP/1.1
Accept: application/json
Cookie: AuthSession=cm9vdDo1MjA1NEVGMDo1QXNQkqC_0Qmgrk8Fw61_AzDeXw
Host: localhost:5984

響應報文示例如下:

HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 12
Content-Type: application/json
Date: Fri, 09 Aug 2013 20:30:12 GMT
Server: CouchDB (Erlang/OTP)
Set-Cookie: AuthSession=; Version=1; Path=/; HttpOnly

{
    "ok": true
}

2.2 創建與刪除數據庫

創建數據庫就是向服務器發送一個特定的PUT請求即可。
curl命令示例如下:

curl --request PUT \
  --url http://127.0.0.1:5984/db1 \
  --cookie 'AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly'

這里的URL中的路徑中的db1就是數據庫名稱,這個名稱只能是小寫字母和數組,不能是別的。
如果已經存在或別的錯誤,返回的JSON中會有相關信息

{
	"error": "file_exists",
	"reason": "The database could not be created, the file already exists."
}
或數據庫名稱不合規則時候(__user1不符合規則)
{
	"error": "illegal_database_name",
	"reason": "Name: '__user1'. Only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter."
}

刪除數據庫則向服務器發送一個DELETE請求,參數與創建的一致。
curl命令示例如下:

curl --request DELETE \
  --url http://127.0.0.1:5984/db1 \
  --cookie 'AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly'

不存在的時候也會返回相關的信息

{
	"error": "not_found",
	"reason": "Database does not exist."
}

2.3 插入、刪除、更新文檔(記錄)

2.3.1 插入文檔

插入文檔也使用PUT請求,文檔必須插入到某個數據庫內。每個文檔都有一個_id的主鍵,這個鍵的值不能以下划線開頭。如果沒有給定_id則會自動生成一個,類似於f9ba72763355579163d36f31de002246這樣的。
文檔的內容必須是一個合法的json格式。CouchDB中所有預定義的鍵值都是以下划線開頭的,所以所有的鍵都不能以下划線開頭。每個文檔都有一個版本號,創建的時候會自動添加_rev字段表示。

curl插入單個文檔示例:

curl --request PUT \
  --url http://localhost:5984/db1/%E4%B8%AD%E6%96%87 \
  --header 'content-type: application/json'
  --cookie 'AuthSession=bzo1QkJENkRCRToXLIOUaf3twhYIrs-eTTyTwJFB5w; Version=1; Path=/; HttpOnly' \
  --data '
{
    "字符串": "字符串值",
    "數組": [
        "值2",
        2,
        1.234
    ],
    "對象":{
			"key":"值"
		}
}'

上面的路徑參數中的db1就是先前創建的數據庫名,后面的%E4%B8%AD%E6%96%87鍵值兩個字的URL編碼格式,也就是文檔的_id值。
返回結果如下:

{
	"ok": true,
	"id": "鍵值",
	"rev": "1-4fd4c8f7fe3d72bc579f6cfc45f6b0d4"
}

對於批量插入文檔,則需要使用_bulk_docs命令來操作,這個命令需要使用POST方法來請求。
批量插入的時候,將需要插入的多個文檔的內容,放入一個json數組中,每個文檔的_id參數也必須明確指定。
示例如下:
curl插入多個文檔示例:

curl --request POST \
  --url http://localhost:5984/db1/_bulk_docs \
  --header 'content-type: application/json' \
  --cookie AuthSession=bzo1QkJEOUM4QTr6P3NYSJprjQlgFYgeba6cwwBqJw \
  --data '
{
	"docs": [
		{"_id":"s1","desc":"bobo","age":15},
		{"_id":"s2","desc":"小紅","age":19},
		{"_id":"s3","desc":"小明","age":22},
		{"_id":"s4","desc":"ab","age":14}
	]
}'

報文如下:

POST /db1/_bulk_docs HTTP/1.1
Host: localhost:5984
User-Agent: insomnia/6.0.2
Cookie: AuthSession=bzo1QkJENkRCRToXLIOUaf3twhYIrs-eTTyTwJFB5w
Content-Type: application/json
Accept: */*
Content-Length: 175
{
	"docs": [
		{"_id":"s1","desc":"bobo","age":15},
		{"_id":"s2","desc":"小紅","age":19},
		{"_id":"s3","desc":"小明","age":22},
		{"_id":"s4","desc":"ab","age":14}
	]
}

返回結果如下(數組中的每個對象,都和單個插入是一樣的):

[
	{
		"ok": true,
		"id": "s1",
		"rev": "1-5efc8527e2a56dc31e71abe36d365e38"
	},
	{
		"ok": true,
		"id": "s2",
		"rev": "1-959ab718375f00a5b678ece00f68a1f7"
	},
	{
		"ok": true,
		"id": "s3",
		"rev": "1-08ded6f70086c004a2b8ef6bb2439b88"
	},
	{
		"ok": true,
		"id": "s4",
		"rev": "1-ccd6248a85ad565b2b12a3127c1b82d7"
	}
]

2.3.2 刪除文檔

刪除文檔和刪除數據庫類似,也是使用DELETE請求,使用URL中的Path部分指定數據庫和文檔_id
刪除的時候還必須指定文檔的版本,如果沒有指定版本,則會提示更新沖突。
curl刪除單個文檔示例:

curl --request DELETE \
  --url 'http://localhost:5984/dbtest/s3?rev=1-08ded6f70086c004a2b8ef6bb2439b88' \
  --cookie AuthSession=bzo1QkJEOUYxMjr2HOFipeXf2K3e3Qy8QmeKuHgTaw

返回結果示例:

{
	"ok": true,
	"id": "s3",
	"rev": "2-eba8354ebc6964892c780f2d1435dd7f"
}

可以看到,刪除的結果中僅rev值變化了。這時候如果再向數據庫中插入_ids3的文檔,則其_rev值將會變為3-xxxxx...xxx,也就是版本號更新了。

對於刪除多個文檔,也是使用_bulk_docs命令來操作。在POST提交的數據中,JSON對象中docs數組下的每個對象都表示一個要刪除的文檔,必須含有文檔的_id_rev參數,_deleted參數用來指示操作為刪除操作。
curl刪除多個文檔示例:

curl --request POST \
  --url http://127.0.0.1:5984/dbtest/_bulk_docs \
  --header 'content-type: application/json' \
  --cookie AuthSession=bzo1QkJEQTEzOTpmznvulsDVLy38QY1AemMA5LZXNQ \
  --data '{
	"docs": [
		{
			"_id": "s1",
			"_rev": "5-64964a8e3910a7f17b8bd1b2942811bf",
			"_deleted": true
		},
		{
			"_id": "s2",
			"_rev": "5-64964a8e3910a7f17b8bd1b2942811bf",
			"_deleted": true
		},
		{
			"_id": "s4",
			"_rev": "3-e319f63912531859882a9495568fe7f4",
			"_deleted": true
		}
	]
}'

返回結果如下:

[
	{
		"ok": true,
		"id": "s1",
		"rev": "6-266b9d0fda1846ccf8c37facbb2f03ba"
	},
	{
		"id": "s2",
		"error": "conflict",
		"reason": "Document update conflict."
	},
	{
		"ok": true,
		"id": "s4",
		"rev": "4-836b5d321c9eed62ffdbe124f21df167"
	}
]

因為我把s2_rev參數寫錯了,所以未能成功刪除s2

2.3.3 更新文檔

更新文檔和插入文件基本是一致的,只是更新文檔需要指定文檔的_rev值,如果沒有指定則會返回更新沖突。

這里其實好理解可以這么認為CouchDB是沒有插入(刪除)操作的,當指定_id的文檔不存在的時候,就會插入,否則就是更新。如果更新沒有指定_rev參數或參數值不正確,則更新就不會成功,原因是Document update conflict

CouchDB不支持對JSON文檔進行部分更新,必須是全更新。也就是說不能添加或者刪除字段,也不能僅更新某些字段的值。更新文檔的時候_rev 參數必須是最新獲取的,因為任何修改操作都會引起_rev`值變化。

curl更新單個文檔示例:

curl --request PUT \
  --url http://localhost:5984/dbtest/doc4 \
  --header 'content-type: application/json' \
  --cookie 'AuthSession=bzo1QkJEN0ZFRToKbM2PpPtuAYMsfUoiml7T1NesyQ; Version=1; Path=/; HttpOnly' \
  --data '
{
	"_rev":"4-8cf3de6bbe77006418d2f74e570be270",
    "地區": "北京北邊",
	"新的鍵":"新的 值"
}'

返回和插入的返回時一樣的,這里就不寫了。
curl批量更新文檔示例:

curl --request POST \
  --url http://localhost:5984/dbtest/_bulk_docs \
  --header 'content-type: application/json' \
  --cookie AuthSession=bzo1QkJEQTU4NDr5_i2OSSoponSuDz4rLu9fh4NHbw \
  --data '
{
	"docs": [
		{"_id":"s1","_rev":"7-5efc8527e2a56dc31e71abe36d365e38","desc":"bobo2","age":56.32},
		{"_id":"s2","_rev": "6-959ab718375f00a5b678ece00f68a1f7","desc":"小紅2","age":19.36}
	]
}'

返回結果如下:

[
	{
		"ok": true,
		"id": "s1",
		"rev": "8-2951951ea0b4479fc1f2a0210dc83ebe"
	},
	{
		"ok": true,
		"id": "s2",
		"rev": "7-50d7fd758615aa6aefbc6aa2ec86fd8b"
	}
]

2.4 查詢記錄

查詢記錄可以查閱http://docs.couchdb.org/en/latest/api/database/find.html
這里就不再詳細寫具體的請求過程了。

2.4.1 _find查詢

_find命令用來查詢摸個數據庫中的文檔,類似於MongoDBfind操作。
_find命令也使用POST方法請求,提交的數據是一個JSON對象,格式介紹如下:

請求體JSON對象格式

字段 值類型 說明
selector object 用於選擇文檔的標准JSON對象。
相關語法將在后面詳細敘述
limit number 接收返回的最大結果數。默認為25,可選
skip number 跳過前面的N個結果,可選
sort object 排序規則,可選
fields array 指定返回結果含有哪些字段的數組,省略則返回所有字段
use_index string/array 指示查詢使用的特定索引。
可以是"<design_document>"["<design_document>", "<index_name>"],可選
r number 讀取結果的所需法定數量。(有副本的情況)默認為1,可選
bookmarks string 指定所需的結果頁面,用於分頁結果集。默認為null,可選
update boolean 是否在范圍結果之前更新索引。默認為true,可選
stable boolean 是否從stable分片集返回視圖結果,可選
execution_stats boolean 是否在查詢響應中包含統計結果,默認false,可選

curl示例1,查詢所有age字段在5到20之間的文檔

curl --request POST \
  --url http://localhost:5984/dbtest/_find \
  --header 'content-type: application/json' \
  --cookie AuthSession=bzo1QkJEQTU4NDr5_i2OSSoponSuDz4rLu9fh4NHbw \
  --data '{
	"selector": {
		"age": {
			"$gte": 5,
			"$lte": 20
		}
	},
	"fields": ["_id", "_rev", "age", "desc"],
	"execution_stats": true
}'

返回結果如下:

{
	"docs": [
		{
			"_id": "s2",
			"_rev": "2-50d7fd758615aa6aefbc6aa2ec86fd8b",
			"age": 19.36,
			"desc": "小紅2"
		},
		{
			"_id": "s4",
			"_rev": "1-ccd6248a85ad565b2b12a3127c1b82d7",
			"age": 14,
			"desc": "ab"
		}
	],
	"bookmark": "g1AAAAA0eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYkXm4BkOGAyULEsAGrUDgc",
	"execution_stats": {
		"total_keys_examined": 0,
		"total_docs_examined": 15,
		"total_quorum_docs_examined": 0,
		"results_returned": 2,
		"execution_time_ms": 1.0
	},
	"warning": "no matching index found, create an index to optimize query time"
}

selector中可以使用的操作符如下:
具體的還是建議看官方文檔,這里也只是一個摘錄。

操作符 說明 示例
$eq 等於 {"selector":{"desc":{"$qe":"s2"}}}
$ne 不等於 {"selector":{"age":{"$ne":20}}}
$gt 大於 {"selector":{"age":{"$gt":20}}}
$gte 大於等於 {"selector":{"age":{"$gte":20}}}
$lt 小於 {"selector":{"age":{"$lt":20}}}
$lte 小於等於 {"selector":{"age":{"$lte":20}}}
$regex 正則表達式 {"selector":{"address":{"$regex":"北京.*"}}}
$and 參數為數組,表示必須同時匹配 {"selector":{"$and":[{"age":{"$lt":20}},{"address":{"$regex":"北京.*"}}]}}
$or 參數為數組,表示必須匹配其中一個 {"selector":{"$or":[{"age":{"$lt":20}},{"address":{"$regex":"北京.*"}}]}}
$not 表示不匹配給定選擇器的結果 {"selector":{$not:{"address":{"$regex":"北京.*"}}}}
$nor 參數為數組,表示所有選擇器都不匹配,則匹配 {"selector":{"$nor":[{"age":{"$lt":20}},{"address":{"$regex":"北京.*"}}]}}
$all 這個只能用來查詢數組字段,如果文檔中該數組字段的元素包含了參數數組中全部元素,則匹配 {"selector":{{"age":{"$all":[13,14]}}
這里我再次入庫了一批數據,age字段是一個數組,里面都是一些整數值。對於這個例子,如果某個文檔的age字段的數組元素中同時含有13、14這兩個值,則匹配上
$elemMatch 匹配數組字段,符合至少一個條件的文檔 {"selector":{"age":{"$elemMatch":{"$gt":5,"$lt":18}}}}
如果某個文檔的age字段的數組元素中,含有大於(eq)5或小於(lt)20的值,就匹配上
$allMatch 匹配數組字段,符合全部條件的字段 {"selector":{"age":{"$allMatch":{"$gt":5,"$lt":18}}}}
如果某個文檔的age字段的數組元素全部大於(gt)5且小於(lt)18,則匹配上

2.4.2 獲取記錄

可以使用_find來查詢記錄,也可以直接獲取記錄的值。
下面的比較簡單,就簡單的記錄一下。
1、獲取單個記錄
使用GET請求獲取,在URL中指定數據庫和文檔_id
curl示例:

curl --request GET \
  --url http://localhost:5984/dbtest/s1 \
  --cookie AuthSession=bzo1QkJEQTU4NDr5_i2OSSoponSuDz4rLu9fh4NHbw

2、獲取數據庫全部記錄列表
獲取全部記錄列表需要使用_all_docs命令,這里也值演示使用GET方法請求的結果,還可以使用POST請求來操作,可以傳遞更多的參數來控制返回結果。
curl示例如下:

curl --request GET \
  --url http://localhost:5984/dbtest/_all_docs \
  --cookie AuthSession=bzo1QkJEQTU4NDr5_i2OSSoponSuDz4rLu9fh4NHbw

返回結果中只包含文檔的_id_rev字段,如果需要獲取包含文檔所有字段的json,則需在URL后加上請求參數include_docs=true示例如下:

{
	"total_rows": 19,
	"offset": 0,
	"rows": [
		{
			"id": "doc1",
			"key": "doc1",
			"value": {
				"rev": "1-c346e9395d9469f4a0359bbc07327a52"
			}
		},
		.... 此處省略很多....
		{
			"id": "鍵值",
			"key": "鍵值",
			"value": {
				"rev": "1-4fd4c8f7fe3d72bc579f6cfc45f6b0d4"
			}
		}
	]
}

3、使用_bulk_get命令來獲取多個記錄
此處可以參考官方文檔http://docs.couchdb.org/en/latest/api/database/bulk-api.html#db-bulk-get

這個使用和前面的批量刪除差不多,也是使用POST方法請求,然后將請求參數放在content中。
JSON參數對象中的docs數組中的每一個元素是一個json對象,必須含有id鍵,來指定獲取哪一個文檔記錄。可以含有rev鍵值。

curl批量獲取記錄示例:

curl --request POST \
  --url http://127.0.0.1:5984/dbtest/_bulk_get \
  --header 'content-type: application/json' \
  --cookie AuthSession=bzo1QkJEQTU4NDr5_i2OSSoponSuDz4rLu9fh4NHbw \
  --data '{
	"docs": [
		{
			"id": "s5",
			"rev":"4-753875d51501a6b1883a9d62b4d33f91"
		},
		{
			"id": "s6",
			"rev": "1-46eeb3a2fb10de49fd7cbb3c74db5361"
		},
		{
			"id": "s7"
		}
	]
}'

返回結果示例:

{
	"results": [
		{
			"id": "s5",
			"docs": [
				{
					"error": {
						"id": "s5",
						"rev": "4-753875d51501a6b1883a9d62b4d33f91",
						"error": "not_found",
						"reason": "missing"
					}
				}
			]
		},
		{
			"id": "s6",
			"docs": [
				{
					"ok": {
						"_id": "s6",
						"_rev": "1-46eeb3a2fb10de49fd7cbb3c74db5361",
						"desc": "bobo",
						"age": [
							15,
							16
						]
					}
				}
			]
		},
		{
			"id": "s7",
			"docs": [
				{
					"ok": {
						"_id": "s7",
						"_rev": "1-9f2b329717a1d2a6d6193328312e5b83",
						"desc": "小明",
						"age": [
							22,
							23
						]
					}
				}
			]
		}
	]
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM