Остановите Mongoose для создания свойства _id для элементов массива вложенных документов

227

Если у вас есть массивы вложенных документов, Mongoose автоматически создает идентификаторы для каждого из них. Пример:

{
    _id: "mainId"
    subDocArray: [
      {
        _id: "unwantedId",
        field: "value"
      },
      {
        _id: "unwantedId",
        field: "value"
      }
    ]
}

Есть ли способ сказать Mongoose не создавать идентификаторы для объектов в массиве?

Атлас
источник

Ответы:

288

Это просто, вы можете определить это в подсхеме:

var mongoose = require("mongoose");

var subSchema = mongoose.Schema({
    //your subschema content
},{ _id : false });

var schema = mongoose.Schema({
    // schema content
    subSchemaCollection : [subSchema]
});

var model = mongoose.model('tablename', schema);
throrin19
источник
2
будет ли это пропускать _idполя даже в коллекции подсхемы или только в том случае, если подсхема используется для встраивания в массив элементов поддокумента? Я спрашиваю об этом, в частности, из-за моего собственного вопроса о SO сегодня.
Веб-пользователь
1
Я использую два уровня вложенных коллекций подсхем. Другими словами, у меня есть коллекция подсхемы, похожая на ваш пример. В рамках этого я использую другую коллекцию подсхем. Я хочу, чтобы только экземпляры модели подсхем первого уровня не использовали идентификаторы, но экземпляры модели подсхем второго уровня (вложенные) должны иметь идентификаторы. Когда я использую ваше решение, то есть указание { _id: false }, оба уровня подсхемы не имеют идентификаторов. Есть ли способ обойти это поведение?
Веб-пользователь
1
Вы пытались установить третий уровень { _id : true }?
throrin19
вчера я попытался изменить это: let studentSchema = new Schema({ studentId: { type: ObjectId, ref: Student.modelName }, performance: [performanceSchema] }, { _id: false });на это: let studentSchema = new Schema({ _id: false, id: false, studentId: { type: ObjectId, ref: Student.modelName }, performance: [performanceSchema] });и это остановило _idсоздание, studentSchemaно сохранило _idсоздание объектов в performanceмассиве поддокументов. Не уверен, что и то _id: falseи другое id: falseнужно.
Веб-пользователь
Спасибо, лучший способ для меня.
Swetabja Hazra
128

Вы можете создавать вложенные документы без схемы и избежать _id. Просто добавьте _id:falseв вашу декларацию под-документа.

var schema = new mongoose.Schema({
   field1:{
      type:String
   },
   subdocArray:[{
      _id:false,
      field :{type:String}
   }]
});

Это предотвратит создание _idполя в вашем поддокне.

Проверено в мангусте v5.9.10

Джоэл Гренон
источник
42

Кроме того, если вы используете литеральный синтаксис объекта для указания подсхемы, вы также можете просто добавить ее _id: falseдля подавления.

{
   sub: {
      property1: String,
      property2: String,
      _id: false
   }
}
wlingke
источник
26

Я использую mongoose 4.6.3, и все, что мне нужно было сделать, это добавить в схему _id: false, не нужно создавать подсхему.

{
    _id: ObjectId
    subDocArray: [
      {
        _id: false,
        field: "String"
      }
    ]
}
jemiloii
источник
Есть ли способ сделать уникальным для всей коллекции?
Сайтама
Вероятно, не с этим методом, но вы всегда можете попробовать. _idэто поле, а не ограничение.
Джемилойи
если при создании _id = mongoose.Types.ObjectId()этого поддокумента я явно назначу , будет ли _id уникальным для всей коллекции?
Сайтама
просто откройте новое переполнение стека, таким образом, вы можете получить много людей, чтобы ответить сразу ~
jemiloii
4

Вы можете использовать любой из

var subSchema = mongoose.Schema({
//subschema fields    

},{ _id : false });

или

var subSchema = mongoose.Schema({
//subschema content
_id : false    

});

Проверьте вашу версию мангуста, прежде чем использовать второй вариант

Дикша Шарма
источник
1

Если вы хотите использовать предопределенную схему (с _id) в качестве вложенного документа (без _id), вы можете сделать следующее теоретически:

const sourceSchema = mongoose.Schema({
    key : value
})
const subSourceSchema = sourceSchema.clone().set('_id',false);

Но это не сработало для меня. Поэтому я добавил, что:

delete subSourceSchema.paths._id;

Теперь я могу включить subSourceSchema в родительский документ без _id. Я не уверен, что это чистый способ сделать это, но это работает.

Оливер Уайт
источник