mongodb nodejs - 转换圆形结构

Posted

技术标签:

【中文标题】mongodb nodejs - 转换圆形结构【英文标题】:mongodb nodejs - converting circular structure 【发布时间】: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);
);

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

【问题讨论】:

您是否尝试过记录查询的输出? 【参考方案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);
);

【讨论】:

啊,是的,我从另一个 *** 答案中提取了原始代码,我猜这在语法上是不正确的。不过,您提供的那个有效,谢谢! 不客气 ;).. 这种事情经常发生在 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 指向,这是您要查询的文档。

【讨论】:

以上是关于mongodb nodejs - 转换圆形结构的主要内容,如果未能解决你的问题,请参考以下文章

mongodb的作品目录

如何在nodejs mongodb本机驱动程序中将字符串转换为ObjectId?

如果这个nodejs rest api没问题并且它的mongoose结构和mongodb数据,为啥我从mongoDB得到空值?

用golang的mgo驱动,mongodb时区怎么设置,总是慢8小时

如何将sql查询转换为mongodb查询中的exists

Python访问MongoDB,并且转换成Dataframe