gpt4 book ai didi

ruby-on-rails - Rails 3 计算嵌入式记录的年龄

转载 作者:可可西里 更新时间:2023-11-01 09:52:42 27 4
gpt4 key购买 nike

我正在使用 mongodb,并且有一个模型可以将评论添加为嵌入式文档。

如何获取条目评论的平均年龄? (相对示例,我的字段略有不同)

所以我可以对一个条目有很多评论,我需要找出评论的平均年龄,或者平均 :cal_date。收集其他指标会很好,例如所有条目/评论或每个条目的最大 :cal_date...

这有意义吗?需要更多细节?我很高兴有义务得到解决方案。一段时间以来,我一直对日期计算感到困惑。

另一种思考方式是使用图书馆书籍模型:有很多书,每本书都有很多借阅/借阅。我需要找出每本书的平均借出时间所有书籍借出的平均时间。同样,只是指标,但这些都是日期这一事实令人困惑。

{
_id: ObjectId("51b0d94c3f72fb89c9000014"),
barcode: "H-131887",
comments: [
{
_id: ObjectId("51b0d94c3f72fb89c9000015"),
cal_date: ISODate("2013-07-03T16:04:57.893Z"),
cal_date_due: ISODate("2013-07-03T16:04:57.894Z")
},
{
_id: ObjectId("51b0e6053f72fbb27900001b"),
cal_date: ISODate("2012-07-03T19:39:43.074Z"),
cal_date_due: ISODate("2013-07-03T19:39:43.076Z"),
updated_at: ISODate("2013-06-06T19:41:57.770Z"),
created_at: ISODate("2013-06-06T19:41:57.770Z")
}
],
created_at: ISODate("2013-06-06T18:47:40.481Z"),
creator_id: ObjectId("5170547c791e4b1a16000001"),
description: "",
maker: "MITUTOYO",
model: "2046S",
serial: "QEL228",
status: "Out",
updated_at: ISODate("2013-06-07T18:54:38.340Z")
}

还有一件事如何使用 $push 在我的输出中包含其他字段?我可以让它工作,但它包括,比如条形码,在数组中两次 "barcode"=> ["H-131887", "H-131887"]

最佳答案

你没有说你想要年龄的时间单位,但我只是想告诉你如何在几分钟内取回它,相信你能想出如何将它转换成任何其他时间单位。我将假设原始文档具有这样的架构:

{ _id: xxx,
post_id: uniqueId,
comments: [ { ..., date: ISODate() }, ..., { ... , date: ISODate() } ],
...
}

现在聚合:

// first you want to define some fixed point in time that you are calculating age from.
// I'm going to use a moment just before "now"
var now = new Date()-1
// unwind the comments array so you can work with individual comments
var unwind = {$unwind:"$comments"};
// calculate a new comment_age value
var project = {$project: {
post_id:1,
comment_age: {
$divide:[
{$subtract:[now, "$comments.date"]},
60000
]
}
} };
// group back by post_id calculating average age of comments
var group = {$group: {
_id: "$post_id",
age: {$avg: "$comment_age"}
} };
// now do the aggregation:

db.coll.aggregate( unwind, project, group )

您可以使用 $max、$min 和其他分组函数来查找最旧和最新评论日期或最低/最高评论年龄。您可以按 post_id 分组,也可以按常量分组以查找整个集合的这些计算等。

* 编辑 *以您为“图书馆书籍”包含的文档为例,假设“comments.cal_date”是 checkout 时间并且所有评论的最新 cal_date 表示当前“ checkout ”(已返回旧的):

 db.coll.aggregate( [
{ $match : { status : "Out" } },
{ $unwind : "$comments" },
{ $group : { _id : "$_id",
cal_date : { $max : "$comments.cal_date" }
}
},
{ $project : { outDuration : { $divide : [
{ $subtract : [
ISODate("2013-07-15"),
"$cal_date"
]
},
24*60*60*1000
]
}
}
},
{ $group : { _id : 1,
avgOut : { $avg : "$outDuration" }
}
}
] )

这些步骤在做什么:

  • 根据 status 过滤掉文档,以仅对当前 Out 的书籍进行计算。
  • $unwind 展平“comments”数组,这样我们就可以
  • 使用 $group$max 查找哪个条目是最新的 cal_date
  • 使用此最大 cal_date(表示图书的借出时间)从今天的日期中减去它,并将结果除以一天中的毫秒数,得到这本书已经借出的天数
  • $group 将所有结果放在一起,找出所有已借出书籍的平均借出天数。

* 编辑 *我假设您知道 Ruby,只需要知道如何执行聚合框架命令来计算日期差异/平均值/等。这是 Ruby 中使用“now”将 cal_date 与(您也可以使用常量日期值进行比较)相同的代码:

# get db collection from MongoClient into variable 'coll'
# see basic MongoDB Ruby driver tutorial for details
coll.aggregate([
{ "$match" => {"status"=>"Out"} },
{ "$unwind" => "$comments"},
{ "$group" => { "_id" => "$_id", "cal_date" => { "$max" => "$comments.cal_date" } } },
{ "$project"=> {
"outDuration" => {
"$divide" => [
{"$subtract" => [ Time.now, "$cal_date" ] },
24*60*60*1000
]
}
}
},
{ "$group" => {
"_id" => 1,
"avgOut" => {"$avg"=>"$outDuration"}
}
}
])

参见 https://github.com/mongodb/mongo-ruby-driver/wiki/Aggregation-Framework-Examples更多示例和解释。

如果您想在 $group 阶段中保留其他字段,您可以通过像这样更改管道步骤来添加更多字段:

    { $group  : { _id : "$_id", 
barcode : { $first : "$barcode" },
cal_date : { $max : "$comments.cal_date" }
}
}

如果您不需要原始的 _id,您可以在第一行中使用“$barcode”而不是“$_id”(即 _id: "$barcode") 但由于可能有多个字段你想保留,$first 技巧可以处理你想保留的字段。

关于ruby-on-rails - Rails 3 计算嵌入式记录的年龄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17029056/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com