【问题标题】:Transform mongodb documents and subdocuments to replace _id with id in a recursive loop转换 mongodb 文档和子文档以在递归循环中将 _id 替换为 id
【发布时间】:2016-02-22 06:03:50
【问题描述】:

我有一个像这样的典型猫鼬示意图集合:

/* 0 */
{
    "name" : "CIMA",
    "_id" : ObjectId("563ff96bb61f6b2c0e82f93e"),
    "subjects" : [],
    "__v" : 0
}

/* 1 */
{
    "name" : "TESTDDD",
    "_id" : ObjectId("563ffa1db61f6b2c0e82f940"),
    "subjects" : [],
    "__v" : 0
}

/* 2 */
{
    "name" : "testing new thing",
    "_id" : ObjectId("564cbc605adf343c0dc49e95"),
    "subjects" : [],
    "__v" : 0
}

/* 3 */
{
    "name" : "asdfsdf",
    "_id" : ObjectId("564cc0f45adf343c0dc49e96"),
    "subjects" : [],
    "__v" : 0
}

/* 4 */
{
    "name" : "asdfasdfasdfasdfasdfsd",
    "_id" : ObjectId("564ced6ed68ef5d00d5ad4db"),
    "subjects" : [],
    "__v" : 0
}

/* 5 */
{
    "__v" : 0,
    "_id" : ObjectId("563ff5de8e3ae0ce0d5f65a7"),
    "name" : "TEST EDITED",
    "subjects" : []
}

/* 6 */
{
    "__v" : 0,
    "_id" : ObjectId("563566b572b65918095f1db3"),
    "name" : "TEST COURSE",
    "subjects" : []
}

/* 7 */
{
    "name" : "sub one",
    "_id" : ObjectId("564d017d4e13a8640e6b1738"),
    "subjects" : [],
    "__v" : 0
}

/* 8 */
{
    "__v" : 0,
    "_id" : ObjectId("563febb75a9909ae0d25d025"),
    "name" : "testing course",
    "subjects" : []
}

/* 9 */
{
    "__v" : 0,
    "_id" : ObjectId("563ff95ab61f6b2c0e82f93d"),
    "name" : "324234",
    "subjects" : []
}

/* 10 */
{
    "__v" : 0,
    "_id" : ObjectId("563ff8d2b61f6b2c0e82f93b"),
    "name" : "asdfasfd",
    "subjects" : [ 
        {
            "name" : "some suject",
            "_id" : ObjectId("564d05842582c8fe0eb4362d"),
            "topics" : []
        }
    ]
}

/* 11 */
{
    "__v" : 0,
    "_id" : ObjectId("563ff8fbb61f6b2c0e82f93c"),
    "name" : "asfdasfasfd",
    "subjects" : [ 
        {
            "name" : "asdfasdfasdfasdfasdfsd",
            "_id" : ObjectId("564d05c82582c8fe0eb4362e"),
            "topics" : []
        }
    ]
}

/* 12 */
{
    "__v" : 0,
    "_id" : ObjectId("563ff735b61f6b2c0e82f938"),
    "name" : "test",
    "subjects" : [ 
        {
            "_id" : ObjectId("564d04e32582c8fe0eb4362b"),
            "name" : "test subject",
            "topics" : []
        }, 
        {
            "name" : "test subject edite",
            "_id" : ObjectId("564d46a4adcf28580f631eca"),
            "topics" : []
        }, 
        {
            "_id" : ObjectId("564d46b4adcf28580f631ecb"),
            "name" : "test subject edited",
            "topics" : []
        }, 
        {
            "name" : "test subject edite again",
            "_id" : ObjectId("564d4759d6fe04640f99701a"),
            "topics" : []
        }, 
        {
            "_id" : ObjectId("564d4793ef24f5670f62ba22"),
            "name" : "test subject yet again",
            "topics" : []
        }, 
        {
            "name" : "test subject edited TWO TIMES",
            "_id" : ObjectId("564d4989ef24f5670f62ba23"),
            "topics" : []
        }
    ]
}

现在,无论文档在嵌套结构中的哪个级别,我都需要客户端接收所有 _id 替换为 id 的内容。所以我写了一个这样的转换递归函数:

var _ = require('underscore');

module.exports = {
    toClient: transformCollection
}

function transformCollection(theObject) {
var result = null, object = {};

if(theObject instanceof Array) {
    for(var i = 0; i < theObject.length; i++) {
        theObject[i] = process.nextTick(function () {transformCollection(theObject[prop]);}); // <----Assignment
    }
}
else
{
    for (var prop in theObject) {
        if (prop == '_id') {
            theObject.id = theObject._id; // <----Typo
            delete theObject._id;
            delete theObject.__v;
        }
        else if (theObject[prop] instanceof Array) {
            theObject[prop] = process.nextTick(function () {transformCollection(theObject[prop]);}); // <----Assignment
        }
    }
}
return theObject;
   }

并称为:

  courseModel.find(function(err,courses){
            if(err){
                res.json(error.dbRetrievalError);
            }
            else
            {
                res.json(utils.toClient(courses));
            }
        })

这里有几个问题:

  1. 这是实现这一目标的正确方法吗?

  2. 如果是,那么任何人都可以将我的递归函数指向正确的方向吗?一世 收到最大调用堆栈大小超出错误。

【问题讨论】:

  • 可能相关? (如果这能解决问题,那么...#1 的答案是确定的stackoverflow.com/questions/14463087/…
  • 小心给猫鼬一些指点,或者为什么这会造成问题?
  • 聚合方法也存在于猫鼬中。如果可以直接用 mongodb 做,那你也可以用 mongoose 做。
  • 这是另一种方式:stackoverflow.com/questions/7034848/… 虽然我会避免这种方法,但我不想强制所有路由将 _id 替换为 id。我更喜欢……逐案。
  • 所有这些的问题是它们不处理嵌套的子文档。这就是我卡住的地方!

标签: node.js mongodb recursion mongoose


【解决方案1】:

看起来您在递归结果中遗漏了几个作业。在你的 for-in 中还有一个错字,你设置了 object.id 而不是 theObject.id

这行得通吗?

function transformCollection(theObject) {
    var result = null, object = {};

    if(theObject instanceof Array) {
        for(var i = 0; i < theObject.length; i++) {
            theObject[i] = transformCollection(theObject[i]); // <----Assignment
        }
    }
    else
    {
        for (var prop in theObject) {
            if (prop == '_id') {
                theObject.id = theObject._id; // <----Typo
                delete theObject._id;
            }
            else if (theObject[prop] instanceof Array) {
                theObject[prop] = transformCollection(theObject[prop]); // <----Assignment
            }
        }
    }
    return theObject;
}

【讨论】:

  • 要修复超出的调用堆栈,您需要将对 transformCollection 的调用推送到下一个刻度。 process.nextTick(function () {transformCollection(theObject[prop]);});
  • 结合@KevinB,我得到一个所有属性都映射为空的数组。没用!
猜你喜欢
  • 2015-04-02
  • 2021-02-21
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多