在CouchDB中向现有文档添加字段

时间:2014-05-23 06:30:21

标签: python json couchdb

我有一个包含大量常规文档的数据库,看起来像这样(来自wiki的例子):

{
 "_id":"some_doc_id",
 "_rev":"D1C946B7",
 "Subject":"I like Plankton",
 "Author":"Rusty",
 "PostedDate":"2006-08-15T17:30:12-04:00",
 "Tags":["plankton", "baseball", "decisions"],
 "Body":"I decided today that I don't like baseball. I like plankton."
}

我使用couchdb-python在Python中工作,我想知道是否可以在每个文档中添加字段。例如,如果我想要一个"位置"领域或类似的东西。

谢谢!

1 个答案:

答案 0 :(得分:4)

关于ID

couchdb中的每个文档都有一个id,无论你是否设置它。存储文档后,您可以通过doc._id字段访问它。

如果您想设置自己的ID,则必须将ID值分配给doc._id。如果您没有设置它,那么couchdb将分配uuid

如果要更新文档,则需要确保具有相同的ID和有效的修订版。如果说您正在博客文章中工作并且用户添加了位置,那么帖子的网址可能是一个很好的ID。在这种情况下,您可以立即访问该文档。

那么修改

在上面的代码段中,您有doc._rev元素。这是修订的标识符。如果您使用已存在的ID保存文档,则couchdb要求您证明该文档仍然是有效的文档,并且您不是要覆盖其他人的文档。

那么如何更新文档

如果您拥有文档的ID,则可以使用db.get(id)函数访问每个文档。然后,您可以像这样更新文档:

doc = db.get(id)
doc['Location'] = "On a couch"
db.save(doc)

我有一个存储天气预报数据的示例。我大约每2小时更新一次预测。一个单独的流程正在查找我从其他提供商那里查看当天推文特征的数据。

这看起来像这样。

doc = db.get(id)
doc_with_loc = GetLocationInformationFromOtherProvider(doc) # takes about 40 seconds. 
doc_with_loc["_rev"]  = doc["_rev"]
db.save(doc_with_loc) # This will fail if weather update has also updated the file.

如果你有同意进程,那么_rev将变为无效,所以你必须有一个失败,例如。这个可以做:

doc = db.get(id)
doc_with_loc = GetLocationInformationFromAltProvider(doc)
update_outstanding = true
while update_outstanding:
    doc = db.get(id) //reretrieve this to get 
    doc_with_loc["_rev"]  = doc["_rev"]
    update_outstanding = !db.save(doc_with_loc)

那我怎么得到ID?

上面建议的一个选项是您主动设置ID,以便您可以检索它。 IE浏览器。如果用户设置附加到URL的给定位置,请使用URL。但是,您可能不知道要更新哪个文档 - 或者甚至有一个流程可以找到所有没有位置并分配位置的文档。

您最有可能正在使用此视图。视图有一个映射器和一个reducer。你将使用第一个,忘记最后一个。带有映射器的视图执行以下操作:

它返回一种简单/转换的查看数据的方式。您可以为每个数据返回多个值或跳过一些值。它会为您发出密钥提供数据,如果您使用_include_docs函数,它会为您提供文档(旁边有_idrev)。

最简单的视图是默认视图db.view('_all_docs')这将返回所有文档,您可能不想更新所有文档。例如,当您定义视图时,视图也将存储为文档。

下一个简单的方法是让视图只返回文档类型的项目。我的数据库中往往有_type="article。如果您将文档存储在关系数据库中,则将其视为标记文档属于某个表。

最后,您可以过滤具有位置的元素,以便您可以在其中迭代所有仍需要位置的文档,并在单独的过程中识别此位置。有关撰写视图的最佳文档可以找到here