4

我正在通过 Meteor 使用 MiniMongo,并且我正在尝试根据一组动态查询创建一个频率表。

我有两个主要领域,localHourlocalDay. 我预计会有很多重叠,我想确定重叠最多的地方。我目前的做法是这样的。

if(TempStats.findOne({
            localHour: hours,
            localDay: day
          })){//checks if there is already some entry on the same day/hour

            TempStats.update({//if so, we just increment frequency
              localHour: hours,
              localDay: day
            },{
              $inc: {freq: 1}
            })

          } else {//if nothing exists yet, we put in a new entry

            TempStats.insert({
              localHour: hours,
              localDay: day,
              freq: 1
            });

          }

本质上,每次我要插入新数据时都会运行此代码。目前它工作正常,因为在插入所有数据后,我可以按频率排序以找出最常出现的时间和日期集(TempStats.find({}, {sort: {freq: -1}}).fetch())。

但是,我正在寻找一种按频率搜索任何键的方法。例如,搜索所有事情最常发生的那一天,而不是日期和时间。以我目前的方式,我需要有多个数据库和不同的插入方法,这有点荒谬。是否有 Mongo(特别是 MiniMongo)解决方案可以根据键进行频率映射?

谢谢!

4

3 回答 3

3

看起来miniMongo实际上不支持聚合,这使得这种操作变得困难。一种解决方法是在每天结束时汇总自己并将该汇总记录插入到您的数据库中(没有小时字段或将其设置为 -1 之类的值)。相反,您也可以在每次插入时更新该记录。这将允许您对两者使用相同的集合,并且在其他数据库中相当常见。

此外,您应该考虑@nickmilon 的第一个建议,因为使用带有 $inc 运算符的 upsert 语句会将您的示例减少为每个数据点的单个操作。

于 2015-04-15T17:02:34.697 回答
2
  1. 关于您的代码的一个小注释:作为 else 语句的部分并不是真正需要的,如果您将其与选项 upsert=true 结合使用,您的更新将完成完整的工作,它将插入一个新文档,并且$inc将设置频率字段根据需要设置为 1 参见:herehere
  2. 对于计算频率的替代方法:假设您将日期存储为 datetime 对象我建议使用聚合(我不确定他们是否在 minimongo 中添加了对聚合的支持)但是有一些解决方案,然后聚合可以使用 datetime运算符如 $hour、$week 等用于过滤和 $count 来计算频率,而无需在数据库中保留计数。
于 2015-04-13T20:33:25.843 回答
1

这基本上是一个简单的 map-reduce 问题。

首先,不要将派生数据分成 2 个字段。这违反了数据库最佳实践。如果数据以这种方式提供给您,请使用它来创建Date对象。我假设您有一堆正在订阅的集合,然后您将所有这些集合到这个临时本地集合中。这是 map-reduce 模式的映射。此时,由于您的查询未知,因此聚合是浪费 CPU(即使它是您的客户端)。首先映射,然后减少。您应该拥有的是一个充满日期时间的集合。TempMapCollection如果你愿意,打电话给它。现在,使用 aforEach()并传入您的 reduce 函数(按天、按小时等)。

您可以缩减为另一个本地集合,或缩减为一个 javascript 对象。我喜欢使用集合,但如果对象很复杂,你会在那里得到所有的 EJSON 错误。由于您的对象只不过是一个日期时间,让我们使用集合。

所以你有类似的东西:

TempMapCollection.find().forEach(function(doc) {
    var date = doc.dateTime.getDate();
    TempReduceCollection.upsert({timequery: hours}, {$inc: {freq: 1}});
})

现在查询你的 reduce 集合。这有一个额外的好处,即如果您想要执行 2 个唯一查询,则无需重新映射。

于 2015-04-16T18:06:10.027 回答