[英]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 Foo
的a instanceof Foo
顯示為true),所以我不確定為什么save()沒有做任何事情。
我試圖將a.save()
作為Promise來處理,而不是將回調交給它,再一次,沒有任何事情發生,也沒有執行then
或catch
。
這真讓我抓狂!! 我確定我忽略了一些愚蠢的東西,但我似乎無法找到它。 任何幫助都會被激活
PS我沒有包括Partition或Field模型/模式,因為我高度懷疑它們是相關的...但如果有人這么認為,請告訴我
PSS只是一個FYI,MongoDB用戶確實有寫訪問權限
根據@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()
中的任何內容,並且文檔未更新
經過一些修修補補......似乎與它有關...
這很成功 :
// 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()
我創建了一個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.