我有某些带有 aname: String
和 a 的文件version: Integer
。
我需要的是每个名称的最高版本的文件列表。
所以我认为我需要group by
在 sql 中执行等效操作,然后为每个名称执行一个having
for版本。max
我不知道从哪里开始使用 mongoDB。如果有人可以对 mongo 终端进行此查询,那将是一个很好的开始,但额外的好处是专门为 MongoMapper 提供 sytnax。
我有某些带有 aname: String
和 a 的文件version: Integer
。
我需要的是每个名称的最高版本的文件列表。
所以我认为我需要group by
在 sql 中执行等效操作,然后为每个名称执行一个having
for版本。max
我不知道从哪里开始使用 mongoDB。如果有人可以对 mongo 终端进行此查询,那将是一个很好的开始,但额外的好处是专门为 MongoMapper 提供 sytnax。
如果您使用的是 Mongodb 2.2+ 版,则可以使用聚合框架和 group 管道运算符进行查询。
文档在这里:http ://docs.mongodb.org/manual/reference/aggregation/
MongoMapper 没有聚合框架的帮助器,但您可以直接使用 Ruby 驱动程序(驱动程序版本 1.7.0+ 具有聚合帮助器方法)。您必须获取 Mongo::Collection 的实例并在其上调用聚合方法。例如:
Model.collection.aggregate(["$group" =>
{"_id" => "$name",
"max_version" => {"$max" => "$version"}}
])
我希望这会有所帮助!
如果您想使用 Mongo DB 进行分组,请查看Aggregation Framework,它正是完成这项工作的工具!
在这里,您将在聚合框架中找到 GROUP BY、HAVING 等的等价物。
感谢@Simon,我使用 MongoMapper 了解了 Map Reduce。我对它的看法可能并不完美,但它做了我想要它做的事情。这是实现:
class ChildTemplate
...
key :name, String
key :version, Integer, :default => 1
...
private
def self.map
<<-JS
function() {
emit(this.name, this);
}
JS
end
private
def self.reduce
<<-JS
function(key, values) {
var res = values[0];
for(var i=1; i<values.length; i++)
{
if(values[i].version > res.version)
{
res = values[i];
}
}
return res;
}
end
def self.latest_versions(opts = {})
results = []
opts[:out] = "ct_latest_versions"
ChildTemplate.collection.map_reduce(map, reduce, opts).find().each do |map_hash|
results << map_hash["value"]
end
return results
end