如何使用 webtask.io 和 mlab 使用 mongodb find() 获取集合的所有文档

How to get all documents of a collection with mongodb find() using webtask.io and mlab

我在 mlab.com 的 mongodb 中有一个名为 "posts" 的集合,我正在尝试使用 db.collection('posts').find() 访问该集合中的所有文档。下面是我创建的网络任务代码,我将其命名为 mongodb_find:

var MongoClient = require('mongodb').MongoClient;
var waterfall   = require('async').waterfall;

/**
 * @param {secret} MONGO_URL - Mongo database url
 */
module.exports = function(ctx, cb) {

    var MONGO_URL = ctx.data.MONGO_URL;
    if (!MONGO_URL) return cb(new Error('MONGO_URL secret is missing'))

    waterfall([
        function connect_to_db(done) {
            MongoClient.connect(MONGO_URL, function(err, db) {
                if(err) return done(err);
                done(null, db);
            });
        },

        function find_hits(db, done) {
            db
            .collection('posts')
            .find(
                {},
                function (err, result) {
                    if(err) return done( err );
                    done( null, JSON.stringify(result) );
                }
            ).sort({ hits: -1 }).limit( 2 );
        }

    ], cb);

};

我有一个 mongodb_upsert 网络任务,它与此非常相似并且运行完美。但是,对于我的 mongodb_find 任务,我收到以下错误:

{
  "code": 400,
  "error": "Error when JSON serializing the result of the JavaScript code.",
  "details": "TypeError: Converting circular structure to JSON",
  "name": "TypeError",
  "message": "Converting circular structure to JSON",
  "stack": "TypeError: Converting circular structure to JSON\n    at Object.stringify (native)\n    at /data/sandbox/lib/sandbox.js:775:48\n    at /data/sandbox/node_modules/async/dist/async.js:473:16\n    at next (/data/sandbox/node_modules/async/dist/async.js:5315:29)\n    at /data/sandbox/node_modules/async/dist/async.js:958:16\n    at /data/io/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/webtask.js:27:6\n    at handleCallback (/data/_verquire/mongodb/2.0.48/node_modules/mongodb/lib/utils.js:96:12)\n    at Collection.find (/data/_verquire/mongodb/2.0.48/node_modules/mongodb/lib/collection.js:354:44)\n    at find_hits (/data/io/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/webtask.js:23:5)\n    at nextTask (/data/sandbox/node_modules/async/dist/async.js:5310:14)"
}

从命令行连接到 mongodb 时,相同的 find() 命令正常工作:

db.posts.find({}).sort({hits: -1}).limit(2);

集合中的文档是这样设置的:

{
    "_id": {
        "$oid": "5a3ff239bda4eaa4ab96ef8b"
    },
    "title": "Testing 6",
    "url": "/jquery/2017/12/22/testing-6.html",
    "hits": 2
}

有谁知道这个问题的解决方案吗?谢谢。

Collection.find returns a cursor, not the results of the query. You probably want to chain all your operations such as sort and limit on the cursor, then use toArray to define the callback. toArray 将从游标中检索结果。

例如:

function find_hits(db, done) {
  db.collection('posts')
    .find({})
    .sort({ hits: -1 })
    .limit(2)
    .toArray(function (err, result) {
      if(err) return done( err );
      done(null, JSON.stringify(result));
    });
}