簡體   English   中英

更新使用Mongoose模型檢索並作為承諾處理的文檔時出現問題

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

跳轉到更新#2以獲得更詳細的信息

我對從通過Mongoose模型查詢容器檢索到的文檔進行簡單更新時遇到問題。 find查詢確實有兩個群體,但除此之外,我不確定問題是什么

我遇到的問題是,當我檢索文檔,更新屬性,然后嘗試通過Mongooses Doc.save()方法將更新保存到文檔時,似乎沒有任何事情發生。 什么是奇怪的,是save()甚至沒有觸發傳遞給它的回調..(或者如果我作為Promise處理它, then()觸發then()catch()

型號:資產

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 )
}

而且僅僅是為了一些細節,下面是來自相同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")
            }
        ]
    }
]

文檔查詢

下面是我通過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() )

在控制台中,一切都按預期顯示,直到a.save() ..既不是錯誤也不是Updated! 被陳列。

它絕對是我正在與之交互的Mongoose文檔( a instanceof Fooa instanceof Foo顯示為true),所以我不確定為什么save()沒有做任何事情。

我試圖將a.save()作為Promise來處理,而不是將回調交給它,再一次,沒有任何事情發生,也沒有執行thencatch

這真讓我抓狂!! 我確定我忽略了一些愚蠢的東西,但我似乎無法找到它。 任何幫助都會被激活

PS我沒有包括PartitionField模型/模式,因為我高度懷疑它們是相關的...但如果有人這么認為,請告訴我

PSS只是一個FYI,MongoDB用戶確實有寫訪問權限

更新#1

根據@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() )

沒有更改...控制台中沒有顯示a.save()中的任何內容,並且文檔未更新

更新#2

經過一些修修補補......似乎與它有關...

這很成功

// 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()
    })
})

這是不成功的

// 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() )

我能想到的唯一區別是承諾,而不是回調

什么超級奇怪 ...... .then()一些代碼執行..只是不是save()

更新#3

我創建了一個github問題 ,並根據我的上次更新..

我發現了這個問題 ,他的“解決方案”是將整個主要版本從4.X降級到3.X ......

我目前的版本是^ 4.3.7 ,我試圖將其更改為3.8.35 ,降級順利然后腳本本身就拋出了一堆錯誤......老實說,id真的沒有使用這么老的版本反正。

我使用您提供的架構復制了您遇到的問題並找到了解決方案。 以下內容適用於我並更新了.value屬性。 嘗試在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() )

我也使用.exec()因為根據文檔查詢不是完整的承諾 (以防萬一)。 由於.save()返回一個promise,你應該返回它,以便promises按順序解析; 在執行之前等到先前的承諾完成。 這里發布代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM