【问题标题】:Ruby finding duplicates in MongoDBRuby 在 MongoDB 中查找重复项
【发布时间】: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 类中将其作为标准 upsert method 公开)。 Upsert 的意思是“如果找到就更新,否则插入新文档”。
  • 如果您担心唯一索引的开销(并且可以在清理它们之前存在重复的文档),您还可以考虑使用Aggregation Framework 来查找重复项。这将比您使用 Map/Reduce 的原始概念更高效,并且您可能会根据上次重复检查的时间戳或 ObjectID 来限制文档。但是,如果您正在更新这些文档或者重复的可能性很高,那么唯一索引方法肯定会不那么复杂。
  • @Stennie 我来看看聚合框架方法。我对唯一索引进行了测试,发现它只适用于初始构建,而这不起作用。

标签: ruby mongodb ruby-on-rails-4 mongoid


【解决方案1】:

我使用 Stennie 使用聚合框架在问题的 cmets 中提出的建议使其工作。它看起来像这样:

results = Entry.collection.aggregate([
  { "$group" => { 
    _id: { "external_id" => "$external_id"}, 
    recordIds: {"$addToSet" => "$_id" },
    count: { "$sum" => 1 } 
  }}, 
  { "$match" => { 
    count: { "$gt" => 1 } 
  }}
])

然后我遍历结果并删除所有不必要的条目。

【讨论】:

    猜你喜欢
    • 2018-01-30
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    • 2015-01-15
    • 2020-07-18
    相关资源
    最近更新 更多