有什么区别[{type:String}]和{type:[String]} in mongoose?

6ojccjat  于 2023-08-06  发布在  Go
关注(0)|答案(2)|浏览(87)

我试图获取数据,以便如果没有值被分配给字段,它不应该出现在集合中。
我试过这个:

const CollectionSchema = new Schema({
  field1: [{ type: String, default: undefined}],
});

OR

const CollectionSchema = new Schema({
  field1: [{ type: String, default: () => undefined}],
});

字符串
这并没有工作,每当我试图创建它空field1:[]显示。
但后来这个密码起作用了在两个给定的代码段中,创建嵌套数组时,如果没有添加数据,则不显示字段,这两个代码段有什么区别?

const CollectionSchema = new Schema({
  field1: { type: [String], default: () => undefined},
});

wwodge7n

wwodge7n1#

使用[{ type: String, default: undefined}]创建一个以string为元素的field1数组。如果没有值,你将在数组中有未定义的元素。这就是为什么它不工作。
换句话说,等效代码为:

const CollectionSchema = new Schema({
  field1: [fieldSchema],
});
const fieldSchema = new Schema({
  field : { type: String, default: undefined},
});

字符串
正如你所看到的,field1不会是undefined。
使用{ type: [String], default: () => undefined},您只需创建一个字符串数组。这就是为什么它有效。

lp0sw83n

lp0sw83n2#

  • “ Mongoose ”:“^7.3.1”*

在Alternate declaration syntax for arrays文档中:
如果您创建了一个带有对象数组的模式,Mongoose会自动为您将对象转换为模式
请参见下面的示例:

// @ts-nocheck
import assert from 'assert';
import mongoose from 'mongoose';
import { config } from '../../config';

mongoose.set('debug', true);

const schema1 = new mongoose.Schema({
    field1: [
        {
            type: {
                type: String,
                default: undefined,
            },
        },
    ],
});
const Model1 = mongoose.model('test1', schema1);

const fieldSchema = new mongoose.Schema({
    type: {
        type: String,
        default: undefined,
    },
});
const schema2 = new mongoose.Schema({
    field1: [fieldSchema],
});
const Model2 = mongoose.model('test2', schema2);

const schema3 = new mongoose.Schema({
    field1: { type: [String], default: undefined },
});
const Model3 = mongoose.model('test3', schema3);

(async function main() {
    try {
        await mongoose.connect(config.MONGODB_URI);

        // test
        assert.equal(schema1.childSchemas.length, 1);
        assert.ok(schema1.childSchemas[0]?.schema.$implicitlyCreated);
        assert.equal(schema2.childSchemas.length, 1);
        assert.ok(!schema2.childSchemas[0]?.schema.$implicitlyCreated);

        await Promise.all([Model1, Model2, Model3].map((m) => m.create({})));

        const [r1, r2, r3] = await Promise.all([Model1, Model2, Model3].map((m) => m.findOne()));
        console.log('r1: ', r1?.toObject());
        console.log('r2: ', r2?.toObject());
        console.log('r3: ', r3?.toObject());
    } catch (error) {
        console.error(error);
    } finally {
        await mongoose.connection.close();
    }
})();

字符串
两柴记录:

Mongoose: test1.insertOne({ _id: ObjectId("64a2a770ed61e033b5a9736b"), field1: [], __v: 0 }, {})
Mongoose: test2.insertOne({ _id: ObjectId("64a2a770ed61e033b5a9736c"), field1: [], __v: 0 }, {})
Mongoose: test3.insertOne({ _id: ObjectId("64a2a770ed61e033b5a9736d"), __v: 0 }, {})
Mongoose: test1.findOne({}, {})
Mongoose: test2.findOne({}, {})
Mongoose: test3.findOne({}, {})
r1:  { _id: new ObjectId("64a2a770ed61e033b5a9736b"), field1: [], __v: 0 }
r2:  { _id: new ObjectId("64a2a770ed61e033b5a9736c"), field1: [], __v: 0 }
r3:  { _id: new ObjectId("64a2a770ed61e033b5a9736d"), __v: 0 }


r3是你需要的。
Mongoose会将{ type: { type: string, default: undefined } }对象转换为schema,并将schema.$implicitlyCreated属性设置为true,参见源代码:

const childSchema = new Schema(castFromTypeKey, childSchemaOptions);
childSchema.$implicitlyCreated = true;
return new MongooseTypes.DocumentArray(path, childSchema, obj);


schema1schema2是等价的。模式定义意味着它们有一个field1路径,它包含一个子文档数组。
schema3表示它有一个field1路径,默认值为undefined
default模式类型是为type路径设置默认值**而不是field1路径。**这就是为什么当您插入新文档时,field1始终是空数组。

相关问题