【问题标题】:Mongoose update returns undefined猫鼬更新返回未定义
【发布时间】:2017-11-16 01:04:23
【问题描述】:

如何使用最初设置为空对象的新属性更新字段?

例如,我有以下架构:

import mongoose from 'mongoose';

var RunSchema = mongoose.Schema(
  {
    runId: { type: String },
    reports: {
      cookieSummary: {
        name: String,
        path: String
      }
    }
  }
)

export default mongoose.model('Run', RunSchema);

我正在尝试更新以下文档:

{
    "_id": {
        "$oid": "5a0565c2537e0b5d9d08ee6b"
    },
    "__v": 0,
    "reports": {},
    "runId": "8r4LNN3fRqd3qNgdW"
}

但是当我运行这段代码时,它返回undefined:

  Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'}, 
  {
    $set: {'reports.cookieSummary': { 'name': 'test' }},
  }, (err, doc) => { console.log(doc) })

object 表示法在将type 添加到字段后起作用,如下所示:name: { type: String }

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    尝试使用点表示法,因为您只设置了一个字段:

      Run.findOneAndUpdate(
       { runId: '8r4LNN3fRqd3qNgdW' }, 
       { $set: {'reports.cookieSummary.name': 'test' } },
       (err, doc) => { console.log(doc) })
    

    According to the docs,您使用的命令应该可以工作,但您写错了。试试这样:

     Run.findOneAndUpdate(
      { runId: '8r4LNN3fRqd3qNgdW' }, 
      { $set: { 'reports.cookieSummary': {'name': 'test'} } },
      (err, doc) => { console.log(doc) })
    

    如果它不起作用,当你使用这样的命令时,也许 mongo 期望对象匹配它的模式。但我不这么认为。

    告诉我。

    【讨论】:

    • 这行得通,但是如果我需要向cookieSummary 对象添加10 个属性怎么办?我是否有其他选择,或者这是唯一的解决方案,这意味着我应该对所有这些选择使用相同的方法?
    • 第二种解决方案在reports.cookieSummary上返回错误:Unexpected token, expected ,
    • 试过了,还是undefined
    【解决方案2】:

    您对更新文档的查询很好,只是错误出现在 $set 的大括号末尾。您在最后输入了不必要的逗号,在这种情况下实际上会产生问题。所以我建议你删除它并运行它:

    Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'}, 
    {
    $set: {'reports.cookieSummary': { 'name': 'test' }}
    }, (err, doc) => { console.log(doc) });
    

    然后看看。您的其余查询都很好。

    希望它对你有用。 谢谢。

    【讨论】:

    • 试过了,我仍然收到undefined
    • 如果可能的话,您能否将您的查询发送到这里。请一次使用: Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'}, { $set: {'reports.cookieSummary': { 'name': 'test' }} }).exec((err, doc) => { console.log(doc) });使用 exec() 函数
    • 我尝试使用 exec() 函数,它返回 null
    • @Valip 我认为您仍然缺少一些东西。我告诉你的查询很好。请发送您的查询。请确保您在 DB 中的条目也与此 runID 相对应。
    【解决方案3】:

    尝试使用以下代码,它将更新文档并返回更新后的文档。

    var Q = require('q');
    
    var deferred = Q.defer();
    Run.findOneAndUpdate({ runId: '8r4LNN3fRqd3qNgdW' }, { $set: { 'reports.cookieSummary.name': 'test' } }, { new: true },
        (err, doc) => {
            console.log(doc);
            deferred.resolve(doc);
        });
    return deferred.promise;
    

    【讨论】:

    • 它返回null
    • @valip - 我已经根据您的需要编辑了我的答案。由于 findOneAndUpdate 是一个异步函数,它甚至在执行该函数之前就返回了 null。上面的代码使用了 'q' 承诺库,它只有在执行 findOneAndUpdate 函数后才会返回结果..
    • 这正是我已经回答的。点表示法有效,但传递了整个对象{ 'reports.cookieSummary': {'name': 'test'},由于某种原因不是。
    【解决方案4】:

    我做了一个小改动。测试这个解决方案。

        Run.findOneAndUpdate({runId: '8r4LNN3fRqd3qNgdW'}, 
        {
            $set: {"reports": {'cookieSummary':{'name': 'test'}}},
        }, (err, doc) => { console.log(doc) })
    

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 2015-01-06
      • 2021-01-25
      • 1970-01-01
      相关资源
      最近更新 更多