【发布时间】:2014-12-15 11:17:09
【问题描述】:
我正在努力让它有效地工作我认为 map reduce 是答案,但无法让任何工作,我知道这可能是一个简单的答案希望有人可以提供帮助
入门模型如下所示:
field :var_name, type: String
field :var_data, type: String
field :var_date, type: DateTime
field :external_id, type: Integer
如果外部数据源出现故障,我们会得到重复数据。阻止这种情况的一种方法是在使用结果时,我们检查是否已经存在具有相同 external_id 的记录,就像我们已经使用过的一样。然而,这大大减慢了这个过程。现在的计划是每天检查一次重复项。因此,我们正在寻找具有相同 external_id 的条目列表。然后我们可以对那些不再需要的进行排序和删除。
我已经尝试从这里https://coderwall.com/p/96dp8g/find-duplicate-documents-in-mongoid-with-map-reduce 调整 sn-p,如下所示,但得到 p>
因错误 0 失败:“异常:断言 src/mongo/db/commands/mr.cpp:480”
def find_duplicates
map = %Q{
function() {
emit(this.external_id, 1);
}
}
reduce = %Q{
function(key, values) {
return Array.sum(values);
}
}
Entry.all.map_reduce(map, reduce).out(inline: true).each do |entry|
puts entry["_id"] if entry["value"] != 1
end
end
我走了吗?有人可以提出解决方案吗?我正在使用 Mongiod、Rails 4.1.6 和 Ruby 2.1
【问题讨论】:
-
这似乎是一个很好的解决方案。我将在 drop dups 设置为 true 的情况下进行查看。谢谢。
-
仅供参考,
dropDups选项仅适用于唯一索引的初始构建。绝对要谨慎使用,因为如果其中一个副本最近更新,您可能会删除“错误”的副本。除了在external_id字段上添加唯一索引之外,您可能还需要考虑使用upsert(Mongoid 在您的 Model 类中将其作为标准upsertmethod 公开)。 Upsert 的意思是“如果找到就更新,否则插入新文档”。 -
如果您担心唯一索引的开销(并且可以在清理它们之前存在重复的文档),您还可以考虑使用Aggregation Framework 来查找重复项。这将比您使用 Map/Reduce 的原始概念更高效,并且您可能会根据上次重复检查的时间戳或 ObjectID 来限制文档。但是,如果您正在更新这些文档或者重复的可能性很高,那么唯一索引方法肯定会不那么复杂。
-
@Stennie 我来看看聚合框架方法。我对唯一索引进行了测试,发现它只适用于初始构建,而这不起作用。
标签: ruby mongodb ruby-on-rails-4 mongoid