猫鼬返回对象会执行哪些内部操作?

时间:2019-11-27 07:55:39

标签: javascript node.js mongodb express mongoose

我的故事可能有点乏味,但是这个问题我真的很困惑,这里是:
我正在尝试更改服务层中Mongoose静态Model方法返回的商品对象的值,这是该对象的样子:

{
    "_id" : ObjectId("5ddc7ce28251373510d4e49b"),
    "tag" : [
        "Error handling",
        "async/await"
    ],
    "title" : "title",
    "content" : "This is an article",
    "createdAt" : ISODate("2019-11-26T09:16:18.177+08:00"),
    "updatedAt" : ISODate("2019-11-26T10:04:41.636+08:00"),
    "view" : [
        {
            "_id" : ObjectId("5ddc7cee8251373510d4e49c"),
            "email" : "123",
            "viewAt" : ISODate("2019-11-26T09:16:30.733+08:00")
        },
        {
            "_id" : ObjectId("5ddcdcefa4ac2a9f54228a42"),
            "email" : "123",
            "viewAt" : ISODate("2019-11-26T16:06:07.310+08:00")
        },

    ],
    "thumbUp" : [
        {
            "email" : "123",
            "thumbedAt" : ISODate("2019-11-26T16:46:17.870+08:00")
        }
    ],
    "comment" : [
        {
            "_id" : ObjectId("5ddcea9efa1afbbe082cc051"),
            "userId" : "5d836cacc845921e1034f1da",
            "text" : "fff",
            "commentAt" : ISODate("2019-11-26T17:04:30.166+08:00")
        },
    ],
    "__v" : 0
},

然后,我在注释数组中使用userIds进行其他一些数据库查询(例如,获取用户名),并将获取的数据与原始注释数据组合在一起,形成一个新的注释数组。这里是一个新的注释数组:

{
    _id: 5ddcea9efa1afbbe082cc051,
    userId: '5d836cacc845921e1034f1da',
    text: 'This is quite useful!',
    commentAt: 2019-11-27T05:59:21.164Z,
    username: 'Sherr_Y',
    hasAvatar: true
}

然后是问题:当我尝试用新的注释替换原始注释时,我发现没有任何变化。这是我尝试过的:

_data.comment = newCommentArray;
// or
Object.assign(_data, { comment: newCommentArray });

最后我发现_data不是仅包含数据的对象。这就是它的真正外观:

{
  '$__': InternalCache {
    strictMode: true,
    selected: {},
    shardval: undefined,
    saveError: undefined,
    validationError: undefined,
    adhocPaths: undefined,
    removing: undefined,
    inserting: undefined,
    saving: undefined,
    version: undefined,
    getters: {},
    _id: 5ddc7ce28251373510d4e49b,
    populate: undefined,
    populated: undefined,
    wasPopulated: false,
    scope: undefined,
    activePaths: StateMachine {
      paths: [Object],
      states: [Object],
      stateNames: [Array]
    },
    pathsToScopes: {},
    cachedRequired: {},
    session: undefined,
    '$setCalled': Set {},
    ownerDocument: undefined,
    fullPath: undefined,
    emitter: EventEmitter {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: 0
    },
    '$options': { skipId: true, isNew: false, willInit: true }
  },
  isNew: false,
  errors: undefined,
  _doc: {
    tag: ["Error handling","async/await"],
    _id: 5ddc7ce28251373510d4e49b,
    title: 'title',
    content: 'This is an article',
    createdAt: 2019-11-26T01:16:18.177Z,
    updatedAt: 2019-11-26T02:04:41.636Z,
    view: [
      [Object], [Object]
    ],
    thumbUp: [ [Object] ],
    comment: [ [Object] ],
    __v: 0
  },
  '$locals': {},
  '$init': true
}

很显然,_doc的值正是我们真正需要的。所以我用const res = Object.assign({ ..._data._doc }, { comment });处理了它。现在它可以工作了。即使我可以继续我的工作,我仍然想知道猫鼬返回对象有什么魔力。这里有两个主要问题:

  • 当我尝试以下操作时,它仅显示我们需要的数据(_doc):

    console.log(_data);
    
    // Only output what inside _doc
    

    但是当我尝试以下操作时,它会输出整个对象:

    console.log({ ...data });
    
    // Output the entire object
    

    为什么data{ ...data }在console.log中有不同的行为。是关于javascript内部规则还是由Mongoose设置。以及如何?

  • 当我使用return _data而不是return { ..._data }将其从服务返回给控制器时,我仍然可以通过console.log({ ...data })在控制器层中获取整个对象。但是当我使用时res.json(_data)返回到前端。无论我做什么,我都只能在_doc内部获取数据。好像res.json(_data)只能返回_doc内部的数据。但这是如何完成的?

1 个答案:

答案 0 :(得分:0)

如果创建猫鼬查询来查找数据库中的内容作为答案,您将不仅会收到一个对象,还会是一个猫鼬查询对象,其中包含许多有用的人员,可以调用返回了猫鼬查询对象。在这里,您可以找到有关此查询对象和查询对象方法的更多信息:Monoose Query Object

要更新猫鼬查询对象的某些属性,可以使用以下方法:

queryObject.findOneAndUpdate(conditions, update)

我认为它非常合适