1

创建订单时,文档具有以下架构:

{order:1,startTime:1402442830110}

订单完成后,将db.collection.findAndModify()处理一个操作以设置 endTime,从而生成如下文档:

{order:1,startTime:1402442830000,endTime:1402442930000}

在同一个过程中,我需要设置 order duration,通过减去两个时间来计算:doc.endTime-doc.startTime

是否有操作员或程序可以帮助在一次操作中做到这一点?还是我必须执行两个 FindAndModify 操作,一个设置返回新文档的新数据,另一个设置duration字段?

4

3 回答 3

2

据我了解,翻译成 SQL 你想做这样的事情

UPDATE [Order] SET
    EndTime = GETDATE(),
    Duration = GETDATE() - StartTime
WHERE OrderID = ''

不幸的是,这在 MongoDB 中尚不支持。但是,您仍然可以通过 2 次更新来做到这一点。第一个不一定是a findAndModify,afindOne就够了。

var startTime = db.order.findOne({order: 1}).startTime;
var endTime = new Date();
db.order.findAndModify({
    query: {order: 1},
    update: {$set: {endTime: endTime, duration: endTime - startTime}}
});

实际上,我认为findAndModifyhere 不会为您带来比 pure 任何优势update,除非您想防止同一订单被多次更新。在这种情况下,最好像这样更改条件:

var startTime = db.order.findOne({order: 1}).startTime;
var endTime = new Date();
db.order.findAndModify({
    query: {order: 1, endTime: {$exists: false}},
    update: {$set: {endTime: endTime, duration: endTime - startTime}}
});

在我看来,您应该有一些东西来控制订单的状态,例如已订购/已付款/已取消...锁定带有状态的订单会比{endTime: {$exists: false}}.

于 2014-06-11T01:37:48.520 回答
0

您可以使用聚合框架来执行此操作。下面给出了示例代码:

db.col.aggregate(
[
    {$match:{order:1}},
    {$project:{order:1, startTime:1,endTime:{$add:[new Date().getTime()]}}},
    {$project:{order:1,startTime:1,endTime:1,duration:{$subtract:["$endTime","$startTime"]}}}
])

这是给定管道的执行方式:

  1. $match 将选择符合条件 order=1 的订单
  2. 第一个 $project 将“endTime”属性添加到选定的订单
  3. 第二个 $project 将通过从 endTime 中减去 startTime 将持续时间字段添加到所选订单
于 2014-06-11T01:37:11.123 回答
0

您的代码的第一个问题是:您使用两个不同的单元(即纯 javascript 和 MongoDB)在文档上放置时间戳。并不是说使用两个不同的程序是错误的,但是在这种情况下,它们返回时间的格式不一样!

你可以让 MongoDB 自己做这一切,也可以让 Nodejs 来做。因为 MongoDB 不允许在其更新查询中进行数学运算,因此最好的方法是通过 javascript 本身(或您用于与 MongoDB 交互的任何东西)来完成此操作。只需将文档拉到您的 orderSave() 中,获取endTime此订单的 ,计算duration并运行:

db.collection.update (
                      {'order' : {$eq: valueOfOrderToUpdate}},
                      {
                         $set : {'endTime': calculatedEndTimeValue},
                         $set : {'duration' : calculatedDuration}
                      },
                      {upsert : true}
);
于 2014-06-11T19:06:41.073 回答