mongodb / mongoose arrayFilters(带有$ [])更新不起作用

时间:2018-10-02 09:40:08

标签: node.js mongodb typescript mongoose

我使用$ []进行的更新无法正常工作。架构:

tables: {
    type: [
        {
            tableID: String,
            numberOfChairs: Number,
            reserved: Boolean,
            location: String,
            inDoors: Boolean,
            reservedDuring: [
                {
                    reservedFrom: Date,
                    reservedTo: Date,
                    reservedFor: {
                        type: mongoose.Schema.Types.ObjectId,
                        ref: 'Consumer'
                    }
                }
            ]
        }
    ],
    required: false
},

我的更新功能:

TableBooking.updateMany({}, {
    '$set': {
        'tables.$[].reservedDuring.$[arr].reservedFrom': Date.now()
    }
}, { arrayFilters: [{
        'arr.reservedFrom': { $gte: Date.now() }
    }],
    multi: true
}, ).then(function (doc)){}

我的更新函数不断返回“ {“ n”:2,“ nModified”:0:“ ok”:1}“。我不知道为什么函数拒绝更新数组元素。我有2个满足arrayfliters条件的文档,但是没有任何改变。我正在使用MongoDB 4.0,猫鼬5.2.14和@ types / mongoose:5.2.12(我在TS中编写我的应用)。

1 个答案:

答案 0 :(得分:0)

好的,我了解:您讲述了模式中的日期格式,但实际上您将字段(reservedFrom和reservedTo)存储为String。因此,您的arrayFilters与好的结果不匹配。 此外,Date.now()将返回时间戳,而不是日期的字符串表示形式或ISODate。 我的建议是使用ISODate而不是String,因为它更易于操作。这里的代码实现了您想要的:

db['TableBooking'].updateMany({}, {
    '$set': {
        'tables.$[].reservedDuring.$[arr].reservedFrom': new ISODate()
    }
}, { arrayFilters: [{
        'arr.reservedFrom': { $gte: new ISODate().toISOString() }
    }],
    multi: true
} )

如果您仍然想使用字符串而不是日期,则必须在$ set阶段在新ISODATE()处添加.toISOString()来稍作修改(就像在arrayFilters中一样)