猫鼬-无法插入字典类型的子文档

时间:2019-11-15 09:07:18

标签: mongodb mongoose mongoose-schema

我有一个Company文档的Mongoose模式,它具有多个字段。其中一个(documents_banks)是字典类型的“自由”字段,因为我事先不知道键的名称。 问题在于,即使保存的文档具有新的sub_docs时,当我保存文档(company.save())时,实际上也没有在数据库中保存新的sub_docs。

var Company = new Schema({
  banks: [{ type: String }], // array of Strings
  documents_banks: {} // free field
});

即使documents_banks不受架构的限制,(在我看来)它也会具有以下结构:

{
  "bank_id1": {
    "doc_type1": {
      "url": { "type": "String" },
      "custom_name": { "type": "String" }
    },
    "doc_type2": {
      "url": { "type": "String" },
      "custom_name": { "type": "String" }
    }
  },
  "bank_id2": {
    "doc_type1": {
      "url": { "type": "String" },
      "custom_name": { "type": "String" }
    }
  }
}

但是我事先不知道键bank_id的名称,也不知道doc_type,所以我使用了字典类型(documents_banks:{})。

现在,以下是我用来在documents_banks中保存新的sub_docs的函数。我总是使用相同的逻辑来保存新的sub_docs。无论如何,这一次似乎已经保存了,但是没有保存。

function addBankDocument(company_id, bank_id, doc_type, url, custom_name) {
  // retrieve the company document
  Company.findById(company_id)
    .then(function(company) {

      // create empty sub_docs if needed
      if (!company.documents_banks) {
        company.documents_banks = {};
      }
      if (!company.documents_banks[bank_id]) {
        company.documents_banks[bank_id] = {};
      }

      // add the new sub_doc
      company.documents_bank[bank_id][doc_type] = {
        "url": url,
        "custom_name": custom_name
      };
      return company.save();
    })
    .then(function(saved_company) {
      // I try to check if the new obj has been saved
      console.log(saved_company.documents_bank[bank_id][doc_type]);
      // and it actually prints the new obj!!
    });
}

saved_company返回的.save()实际上具有新的sub_docs,但是如果我检查数据库,则没有新的sub_doc!我可以只保存第一个,其他所有都不保存。

因此,console.log()始终打印新的sub_docs,但实际上在数据库中,仅保存了第一个sub_doc,而不保存其他sub_doc。因此,最后,saved_company始终有1个sub_doc,第一个。

对我来说,这很奇怪,因为saved_company有新的sub_docs。会发生什么?

以下是DB的真实摘录,它将永远仅包含sub_doc "doc_bank@1573807781414",而DB中将不存在其他内容。

{
  "_id": "5c6eaf8efdc21500146e289c", // company_id
  "banks": [ "MPS" ],
  "documents_banks": {
    "5c5ac3e025acd98596021a9a": // bank_id
    {
      "doc_bank@1573807781414": // doc_type
      {
        "url": "http://...",
        "custom_name": "file1"
      }
    }
  }
}

版本:

$ npm -v
6.4.1

$ npm show mongoose version
5.7.11

$ node -v
v8.16.0

1 个答案:

答案 0 :(得分:0)

似乎,由于猫鼬不知道子文档的确切模型,因此它也不知道何时更改。因此,我必须使用markModified来通过以下方式通知“自由字段”(也称为字典或MixedType)的更改:

    company_doc.documents_banks["bank_id2"]["doc_type3"] = obj; // modify
    company_doc.markModified('documents_banks'); // <--- notify changes
    company_doc.save(); // save changes

据我了解,markModified强制模型在save()期间“更新”该字段。