我想在cloudant分区db(描述为here)中使用只写(不可变)文档策略,其中对于每个文档更新,我都会创建一个具有更新字段的新文档。例如:数据库由订单组成(具有字段order_id,详细信息,time_of_doc_creation)。假设某个订单的详细信息需要更新-我用更新的数据创建一个新文档,并保留order_id。现在,在某个时间点,我想查看系统中的所有订单,并且如果有一些文档的order_id相同,那么只有最新日期的文档才能出现在列表中。
我能想到的唯一方法是从数据库中提取所有文档,然后在客户端由我自己进行过滤,但是我可以在数据库本身中使用某些东西来获得这样的结果吗? / p>
db中的订单列表:
{
order_id:1,
details:"old",
time:"1"
},
{
order_id:2,
details:"old",
time:"2"
},
{
order_id:1,
details:"new",
time:"3"
},
{
order_id:2,
details:"new",
time:"4"
}
所需的输出:给我所有系统中的订单文档,因此db输出应类似于->
{
order_id:1,
details:"new",
time:"3"
},
{
order_id:2,
details:"new",
time:"4"
}
答案 0 :(得分:1)
使用不可变的模型通常会发挥Cloudant的优势,但它并不总是实用甚至不可能的。因此,第一个要问的问题是,如果您选择可变模型,那么文档更新的频率如何?如果要更新某个订单,例如说每秒最多两次,请遵循可变的想法并检查(可能很少)发生冲突。
不可变模型最适合作为更新的替代方案,否则更新将发生在包含列表或对象的一些大型文档中,例如一组快速摄取的时间序列事件等。另一种方法是存储一组 deltas ,然后从视图中获取所有这些deltas的集合,然后将订单缝回客户端。
从我从您的示例中了解到的情况来看,这听起来像是要存储相当于订单的完整,新修订的内容作为新文档,而不是增量,实际上是绕过Cloudant自己的修订系统。这可能不太理想,但是您可能可以找到一些办法。带有示例文件:
function (doc) {
emit([doc.order_id, doc.time], null);
}
要选择订单“ 1”的最新版本,可以发出以下查询:
curl -s -g 'https://skruger.cloudant.com/demo2/_design/queries/_view/orders-by-time?startkey=[2]&endkey=[1]&include_docs=true&reduce=false&descending=true&limit=1'
给出
{
"total_rows": 4,
"offset": 2,
"rows": [
{
"id": "bfd5b38c482b04e45d35b6147adcc82a",
"key": [
1,
3
],
"value": null,
"doc": {
"_id": "bfd5b38c482b04e45d35b6147adcc82a",
"_rev": "1-075a88a11bc842fa0def69556c81ab01",
"order_id": 1,
"details": "new",
"time": 3
}
}
]
}
请注意反向的开始和结束键。如果您想戳上面的数据库,可以打开以供阅读。
答案 1 :(得分:0)
有一种折衷的方法,请使用reduce
功能:
地图功能:
function (doc) {
emit(doc.order_id, [doc.time, doc]);
}
缩小功能:
function (keys, values, rereduce) {
var latest = [0, null];
// I'm not familar with js, maybe you have a better way to find the max record
values.forEach(function(value) {
if (value[0] > latest[0]) {
latest = value;
}
});
return latest;
}
您可以获得以下文件:
{"rows":[
{"key":1,"value":[3,{"_id":"1bebc20edfa9839ee437feda170029f1","_rev":"2-b0209ac4ad56e751d75783e385c57cfb","order_id":1,"details":"new","time":3}]},
{"key":2,"value":[4,{"_id":"1bebc20edfa9839ee437feda1700506e","_rev":"1-db68ad437bc41643ee1dca6435263075","order_id":2,"details":"new","time":4}]}
]}