【问题标题】:mongodb nodejs - converting circular structuremongodb nodejs - 转换圆形结构
【发布时间】:2015-04-27 06:14:49
【问题描述】:

我有一些代码可以从集合中提取所有文档并将其放到网页上。简化版如下所示:

var mongodb = require("mongodb"),
    express = require("express"),
    mongoServer = new mongodb.Server('localhost', 27017),
    dbConnector = new mongodb.Db('systemMonitor', mongoServer),
    db;

var app = new express();

app.get('/drives', function(req, res) {
  db.collection('driveInfo', function(err, collection) {
    if (err) throw err;
    collection.find({}, function(err, documents) {
      res.send(documents);
    });
  });
});

dbConnector.open(function(err, opendb) {
  if (err) throw err;
  db = opendb;
  app.listen(80);
});

我有一个 driveInfo 集合,其中包含一长串文档。每个文档都包含嵌套对象。我想做的是,每当有人在他们的浏览器中访问 /drives 时,将整个集合打印为 json 对象,以便我以后可以使用 jquery 获取所有内容(api 的开头)

但是,我收到一条错误消息,提示“TypeError:将循环结构转换为 JSON”。页面上的错误指向这行代码:

collection.find({}, function(err, documents) {
  res.send(documents);
});

我不确定问题出在哪里,或者自引用在哪里。我没有正确查询集合吗?

【问题讨论】:

  • 您是否尝试过记录查询的输出?

标签: javascript json node.js mongodb


【解决方案1】:

不确定您使用的是什么版本的 API,但我认为从 API 规范看您的语法可能是错误的:

http://docs.mongodb.org/manual/reference/method/db.collection.find/

这是声明:

db.collection.find(<criteria>, <projection>)

而且您肯定在滥用投影参数。像您正在做的那样传递回调似乎会在结果中返回 db 对象,这会导致在 express 中的 JSON 序列化期间出现循环错误。

查找所有操作的正确代码应该是这样的:

collection.find({}).toArray(function(error, documents) {
    if (err) throw error;

    res.send(documents);
});

【讨论】:

  • 啊,是的,我从另一个 stackoverflow 答案中提取了原始代码,我猜这在语法上是不正确的。不过,您提供的那个有效,谢谢!
  • 不客气 ;).. 这种事情经常发生在 Node.js 中,因为 API 不稳定。
【解决方案2】:

在我的情况下,我收到错误是因为我正在查询(使用 mongoose find 方法)而没有等待。请看下文

给出错误的查询(因为我没有使用 await 执行此查询)

const tours = Tour.find({
    startLocation: {
      $geoWithin: { $centerSphere: [[longitude, latitude], radius] }
    }
  });

由于这个原因,我遇到了邮递员的错误:

"message": "Converting circular structure to JSON\n    --> starting at object with constructor 'NativeTopology'\n    |     property 's' -> object with constructor 'Object'\n    |     property 'sessionPool' -> object with constructor 'ServerSessionPool'\n    --- property 'topology' closes the circle"

我如何摆脱上述错误(添加 await):

 const tours = await Tour.find({
        startLocation: {
          $geoWithin: { $centerSphere: [[longitude, latitude], radius] }
        }
      });

【讨论】:

    【解决方案3】:

    回调选项来自 Mongoose 而不是来自 MongoDB see docs

    // Mongoose Docs : callback option
    MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});
    
    
    // Example
    app.get( '/api/users' , (req,res,done)=>{
      let getUsers = NewUser.find({},(err,data)=>{
        if(err) return done(err);
        res.json(data)
      });
    });
    

    看看响应是回调,在你的情况下它会是

    YourModel.find({}, function(err, documents) {
      if(err) return done(err);
      res.send(documents);  //  <-- here
    });
    // <-- not here
    

    在 Mongo 中有一个 游标方法 可以访问文档 next() see docs

    var myCursor = db.bios.find( );
    var myDocument = myCursor.hasNext() ? myCursor.next() : null;
    if (myDocument) {
        var myName = myDocument.name;
        print (tojson(myName));
    }
    

    您可以在 manual/crud 的 mongo 文档中找到 CRUD 操作。在Query Documents 中,您将看到db.inventory.find( {} ):要选择集合中的所有文档,请将一个空文档作为查询过滤器参数传递给 find 方法。


    Async/Await 功能解决方案:Mongo Docs

    app.get( '/api/users' , async (req,res)=>{
      const getUsers = await NewUser.find({});
      res.json( getUsers );
    })
    

    解决方案:Mongoose Docs.

    app.get( '/api/users' , (req,res,done)=>{
      let getUsers = NewUser.find({},(err,data)=>{
        if(err) return done(err);
        res.json(data)
      });
    });
    

    【讨论】:

      【解决方案4】:

      const res1 = await db.collection("some-db").find()

      这里, res1 将包含一个具有循环结构的“光标”,因此会抛出给定的错误。

      尝试在代码中添加const res2 = await res1.toArray()

      这里,res2 现在将包含一个文档数组,由光标 res1 指向,这是您要查询的文档。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多