简体   繁体   English

更新使用Mongoose模型检索并作为承诺处理的文档时出现问题

[英]Having issues updating a document thats retrieved using a Mongoose model and processed as a promise

Jump to update #2 for some closer detail 跳转到更新#2以获得更详细的信息

Im having issues with a simple update to a document retrieved from querying a container via a Mongoose model. 我对从通过Mongoose模型查询容器检索到的文档进行简单更新时遇到问题。 The find query does have two populations, but other than that, im not sure what the issue could be find查询确实有两个群体,但除此之外,我不确定问题是什么

The problem I'm running into, is when I retrieve a document, update a property, then attempt to save the updates to the document via Mongooses Doc.save() method, nothing seems to happen. 我遇到的问题是,当我检索文档,更新属性,然后尝试通过Mongooses Doc.save()方法将更新保存到文档时,似乎没有任何事情发生。 Whats weird, is it the save() doesn't even fire off the callback passed to it.. (Or fire off the then() or catch() if I handle it as a Promise) 什么是奇怪的,是save()甚至没有触发传递给它的回调..(或者如果我作为Promise处理它, then()触发then()catch()

Model: Asset 型号:资产

module.exports = Mongoose => {
    const Schema = Mongoose.Schema

    const assetSchema = new Schema({
        attributes: [{
            _field: {
                type: Schema.Types.ObjectId,
                ref: 'Field',
                required: true
            },
            value: {
                type: Schema.Types.Mixed,
                required: true
            }
        }],
        _partition: {
            type: Schema.Types.ObjectId,
            ref: 'Partition'
        }
    })

    return Mongoose.model( 'Asset', assetSchema )
}

And just for some detail, heres an example result from the same find query with the same two populations 而且仅仅是为了一些细节,下面是来自相同find具有相同两个群体的示例结果

[
    {
        "_id" : ObjectId("56b626dc4040b5383696d16f"),
        "_partition" : { 
            _fields: [Object],
            name: 'Server stuff',
            _id: ObjectId("56ae4707f3d4645b2e5b0537")
        },
        "attributes" : [
            {
                _field: {
                    _id: ObjectId("56ae4703f3d4645b2e5b0534"),
                    name: 'Hostname'
                },
                value: 'server-04.foobar.ad',
                _id: ObjectId("56b626dc4040b5383696d172")
            }
        ]
    }
]

Document Query 文档查询

Heres the code example of where I retrieve some documents via the Foo.find method (which works), and update the value of the first attribute (which I works), but when I try to a.save() the doc.. nothing happens: 下面是我通过Foo.find方法检索一些文件的代码示例(有效),并更新第一个属性(我的工作)的值,但是当我尝试a.save() ,doc ...没什么发生:

Asset
    .find( { _id: '56b6568cb5195902381f6c65' } )
    .populate( { path: 'attributes._field' } )
    .populate( { path: '_partition' } )
    .then( docs => {
        if( ! docs )
            throw new Error(`No docs were found`)

        console.log('# Docs Found:', docs.length) // 1
        console.log('# Instance?:', docs[0] instanceof Asset) // true
        console.log('# Docs:', assets) // Shows single document inside array

        let a = docs[0]

        a.attributes[0].value = 'blah'

        // This is where the problem is, nothing below here is displayed in the console
        a.save(function (err) {
            if (err)
                throw new Error('Failed to update:' + err)

            console.log('Updated!')
        })

    } )
    .catch( err => console.error( 'ERROR:',err ) )
    .finally( () => Mongoose.connection.close() )

In the console, everything displays as expected, right up until the a.save() .. Neither an error or Updated! 在控制台中,一切都按预期显示,直到a.save() ..既不是错误也不是Updated! is displayed. 被陈列。

It's definitely a Mongoose document that I'm interacting with (the a instanceof Foo shows true), so I'm not at all sure why the save() isn't doing anything.. 它绝对是我正在与之交互的Mongoose文档( a instanceof Fooa instanceof Foo显示为true),所以我不确定为什么save()没有做任何事情。

I tried to handle a.save() as a Promise, instead of handing a callback to it, and again, nothing happened at all, neither the then or catch was executed. 我试图将a.save()作为Promise来处理,而不是将回调交给它,再一次,没有任何事情发生,也没有执行thencatch

This is driving me crazy!! 这真让我抓狂!! Im sure its something stupid that I've overlooked, but I cant seem to find it. 我确定我忽略了一些愚蠢的东西,但我似乎无法找到它。 Any help would be appreceated 任何帮助都会被激活

PS I didn't include the Partition or Field models/schemas because I highly doubt they are related... But if someone thinks so, just let me know PS我没有包括PartitionField模型/模式,因为我高度怀疑它们是相关的...但如果有人这么认为,请告诉我

PSS Just an FYI, the MongoDB user does have write access PSS只是一个FYI,MongoDB用户确实有写访问权限

Update #1 更新#1

Per a suggestion from @JohnnyHK, I tried to execute Doc.markModified() : 根据@JohnnyHK的建议,我尝试执行Doc.markModified()

Asset
    .find( { _id: '56b6568cb5195902381f6c65' } )
    .populate( { path: 'attributes._field' } )
    .populate( { path: '_partition' } )
    .then( docs => {
        if( ! docs )
            throw new Error(`No docs were found`)

        console.log('# Docs Found:', docs.length) // 1
        console.log('# Instance?:', docs[0] instanceof Asset) // true
        console.log('# Docs:', assets) // Shows single document inside array

        let a = docs[0]

        a.attributes[0].value = 'blah'

        a.markModified('attributes')

        // This is where the problem is, nothing below here is displayed in the console
        a.save(function (err) {
            if (err)
                throw new Error('Failed to update:' + err)

            console.log('Updated!')
        })

    } )
    .catch( err => console.error( 'ERROR:',err ) )
    .finally( () => Mongoose.connection.close() )

No changes... Nothing in the a.save() is displayed in the console, and the doc isn't updated 没有更改...控制台中没有显示a.save()中的任何内容,并且文档未更新

Update #2 更新#2

After some tinkering.. it seems to be related to it being a promise.. 经过一些修修补补......似乎与它有关...

This is Successful : 这很成功

// AS A CALLBACK
Asset.find( { _id: '56b6568cb5195902381f6c65' } )
    .populate( { path: 'attributes._field' } )
    .populate( { path: '_partition' } )
    .exec(function (err, doc) {
    if (err) throw new Error(err)

    doc[0].attributes[0].value = 'FOO'

    doc[0].save(function (err) {
        if (err) throw new Error(err)

        console.log('Updated to:',doc[0])

        Mongoose.connection.close()
    })
})

This is UNSUCCESSFUL : 这是不成功的

// AS A PROMISE

import Promise from 'bluebird'
Mongoose.Promise = Promise
// ..
Asset.find( { _id: '56b6568cb5195902381f6c65' } )
    .populate( { path: 'attributes._field' } )
    .populate( { path: '_partition' } )
    .then( doc => {
        doc[0].attributes[0].value = 'FOO'

        doc[0].save(function (err) {
            if (err) throw new Error(err)

            console.log('Updated to:',doc[0])
        })
    })
    .catch( err => {
        throw new Error(err)
    })
    .finally( () => Mongoose.connection.close() )

The only difference I can think of is the promise, as opposed to a callback 我能想到的唯一区别是承诺,而不是回调

Whats super weird ... is some of the code inside the .then() executes.. Just not the save() 什么超级奇怪 ...... .then()一些代码执行..只是不是save()

UPDATE #3 更新#3

I created a github issue , and per my last update.. 我创建了一个github问题 ,并根据我的上次更新..

I found this issue , where his "solution" was to downgrade an entire major version, from 4.X to 3.X... 我发现了这个问题 ,他的“解决方案”是将整个主要版本从4.X降级到3.X ......

The version im currently at is ^4.3.7 , I tried to change it to 3.8.35 , which the downgrade went fine but then the script itself threw a bunch of errors... Which honestly, id rather really not use such an old version anyways. 我目前的版本是^ 4.3.7 ,我试图将其更改为3.8.35 ,降级顺利然后脚本本身就抛出了一堆错误......老实说,id真的没有使用这么老的版本反正。

I replicated the issue you are having using the schema you have provided and found a solution. 我使用您提供的架构复制了您遇到的问题并找到了解决方案。 The following worked for me and updated the .value property. 以下内容适用于我并更新了.value属性。 Try prepending return to doc[0].save() to return it as mentioned in this article 尝试在return doc[0].save()将其返回,如本文所述

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
// .....


Asset.find( { _id: '56b6568cb5195902381f6c65' } )
    .populate( { path: 'attributes._field' } )
    .populate( { path: '_partition' } )
    .exec()       // Queries aren't full-fledged promises!
    .then( doc => {
        console.log('Before:',doc[0]);
        doc[0].attributes[0].value = 'FOO'

        // Return a promise!
        return doc[0].save(function(err){
            console.log('Updated to:', doc[0]);
        });
    })
    .catch( err => {
        throw new Error(err)
    })
    .finally( () => Mongoose.connection.close() )

I also use .exec() because according to the docs queries aren't full-fledged promises (just in case). 我也使用.exec()因为根据文档查询不是完整的承诺 (以防万一)。 Since .save() returns a promise, you should return it so that the promises resolve sequentially; 由于.save()返回一个promise,你应该返回它,以便promises按顺序解析; waiting until previous promises complete before executing. 在执行之前等到先前的承诺完成。 Posted the code here 这里发布代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM