【问题标题】:Meteor,Mongo query find every nth documentMeteor,Mongo 查询查找每个第 n 个文档
【发布时间】:2015-03-18 14:03:07
【问题描述】:

我在我的集​​合中使用时间戳,所以每个文档都有一个时间戳,用户希望从“ts1”(时间戳1)到“ts2”获取文档(时间戳 2),但是该间隔内的文档太多,所以我不想只返回每 n 个,例如如果有 100000 个文档,我需要显示 1000 个文档,所以 100000/1000=100。每 100 个文档。

这可能吗,我怎么能做到这一点。

PS。我需要在 Meteor 发布方法中查询这个。

这是我目前得到的:

Meteor.publish('documents-chunk', function (from, to) {
    //get find documents count and get nth
    var count = Documents.find({time: {$gte: from, $lte: to}}).count();
    if (count > 2000) {
        var nth = Math.round(count / 1000);
        return Documents.find(/*query every nth*/);
    }
    return Documents.find({time: {$gte: from, $lte: to}});
});

解决方案:

我~用 Matt K 的回答解决了这个问题。

这就是我所做的:首先我修改了我的收藏并添加了额外的“id”字段:

**

1.

**

Document.find({}, {sort: {time: 1}}).forEach(function (c, i) {
    Document.update(c, {$set: {id: i + 1}});
    console.log(i + 1);
});

这个集合有不到 1,5M 的记录,所以需要一些时间,(还要注意,我必须在这个集合中添加索引 {time: 1} 否则它会导致数据库崩溃)

**

2.

**

Meteor.publish('documents-chunk', function (from, to) {
    var nth = Math.round(Documents.find({time: {$gte: from, $lte: to}}, {sort: {time: 1}}).count() / 1000);
    return Documents.find({time: {$gte: from, $lte: to, $mod: [nth, 0]}}, {sort: {time: 1}});
});

这对我有用,现在我得到了我需要的结果;

我在http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/ 看到不推荐这种方法。但是目前我找不到任何其他解决方案,虽然我发现它是请求https://jira.mongodb.org/browse/SERVER-2397所以也许将来会有更清洁的解决方案,但现在它可以工作。

【问题讨论】:

    标签: mongodb meteor


    【解决方案1】:

    你不能,至少据我所知不能。您有三个选择:

    发布和订阅所有 100,000 个,然后每 1000 个显示一次。从逻辑上讲,您的查询是基于从查询返回的结果数。不管你怎么看,这都是一个两步的过程。

    如果你想变得可爱,你可以让_id(或其他字段)成为一个自动递增的数字。然后,设置var qCount = cursor.count()。然后,查询_id % qCount === 0

    在每创建 1000 条记录时添加一个 sample 字段,然后查询:{$exists: {sample: true}}

    重新思考业务逻辑。每 1000 条记录的附加值是多少?如果要“观察数据”,您可能应该无论如何都要对数据使用聚合来消除异常值。 (这是正确的选择,但说服客户是另一回事……)

    【讨论】:

    • 这种方法的问题是第n个数字与interwal中的总文档不同
    【解决方案2】:

    如果您认为 mongoDB _id 值是真正随机分配的,那么您可以简单地按 _id 排序并选择一组中的前 N ​​个。这将为您提供区间中的 N 个随机值。

    Meteor.publish('documents-chunk', function (from, to) {
      return Documents.find({time: {$gte: from, $lte: to}},{sort: {_id: 1}, {limit: 1000}});
    });
    

    我建议对您返回的随机性进行一些统计。

    【讨论】:

    • 有趣的方法,但是当我在 shell 中测试 2 个查询时:db.documents.find().sort({_id:1}).limit(2) 和 db.documents.find()。 sort({time:1}).limit(2) 他们给我同样的结果(主题但第一次查询要快得多)所以我认为排序后的 Mongo ObjectID 等于时间戳的时间戳,这与 ObjectID 是合乎逻辑的包含时间戳。但在这种情况下,我将获得前 1000 条记录,这不是我需要的。
    • 我检查了迄今为止最大的集合,_id 与 createdAt 的顺序不同,但老实说,我还没有足够的数据来得出明确的结论。
    猜你喜欢
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多