如果文档具有特定密钥,如何获取已删除重复数据的文档列表(时间戳 - 最新胜利)?
How to get list of documents which are deduplicated (on timestamp - latest wins) if the document has a specific key?
我想在 cloudant 分区数据库(描述 here)中使用只写(不可变)文档策略,其中对于每次文档更新,我都会创建一个包含更新字段的新文档。例如:数据库由订单组成(字段 order_id、详细信息、time_of_doc_creation)。假设某个订单的详细信息需要更新 - 我创建了一个包含更新数据并保留 order_id 的新文档。现在在某个时间点,我想查看系统中的所有订单,如果存在 order_id 相同的文档,那么只有最新日期的文档才会出现在列表中。
我能想到的唯一方法是从数据库中提取所有文档,然后在客户端自己进行过滤,但是我可以在数据库中使用一些东西来获得这样的结果?
数据库中的订单列表:
{
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"
}
有一个权衡的方法,使用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}]}
]}
使用不可变模型通常可以发挥 Cloudant 的优势,但这并不总是可行的,甚至是不可能的。因此,第一个要问的问题可能是,如果您选择可变模型,文档更新的频率可能是多少。如果正在更新订单,比如最多每秒几次,请使用可变的想法并检查(可能不频繁)冲突。
不可变模型最适合作为更新的替代方法,否则更新会发生在一些包含列表或对象的大型文档中——比如一组快速摄取的时间序列事件等。另一种方法是存储一个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
}
}
]
}
注意颠倒的开始键和结束键。上面的资料库开放阅读,想戳就戳。
我想在 cloudant 分区数据库(描述 here)中使用只写(不可变)文档策略,其中对于每次文档更新,我都会创建一个包含更新字段的新文档。例如:数据库由订单组成(字段 order_id、详细信息、time_of_doc_creation)。假设某个订单的详细信息需要更新 - 我创建了一个包含更新数据并保留 order_id 的新文档。现在在某个时间点,我想查看系统中的所有订单,如果存在 order_id 相同的文档,那么只有最新日期的文档才会出现在列表中。
我能想到的唯一方法是从数据库中提取所有文档,然后在客户端自己进行过滤,但是我可以在数据库中使用一些东西来获得这样的结果?
数据库中的订单列表:
{
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"
}
有一个权衡的方法,使用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}]}
]}
使用不可变模型通常可以发挥 Cloudant 的优势,但这并不总是可行的,甚至是不可能的。因此,第一个要问的问题可能是,如果您选择可变模型,文档更新的频率可能是多少。如果正在更新订单,比如最多每秒几次,请使用可变的想法并检查(可能不频繁)冲突。
不可变模型最适合作为更新的替代方法,否则更新会发生在一些包含列表或对象的大型文档中——比如一组快速摄取的时间序列事件等。另一种方法是存储一个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
}
}
]
}
注意颠倒的开始键和结束键。上面的资料库开放阅读,想戳就戳。