Mongo:使用元素本身更新字符串数组元素的值



我有一个快速应用程序,我正在使用mongodb来满足我的数据库需求。我的集合结构如下。

集合包含如下所示的文档。

{
_id: 5caa266c58b170106ff17f40,
title: "Test2 88 bulkWrite",
last_save_date: 2019-04-07T17:08:25.149+00:00,
created_by: "McufNwnQX8YXC0tNSa1fdbt9Tus2",
stories: [ { story_id: "1", objects: [...] },
{ story_id: "2", objects: [...] },
{ story_id: "3", objects: [...] },
... 
]    
}

问题很简单,假设用户单击一个按钮,数组元素{story_id: "2", objects: [...]}被删除,并且所有story_id超过 "2" 的元素(s.a., "3", "4"...) 递减 1(变为 "2" 和 "3")。

第一部分,即删除已经完成,但第二部分我无法理解。 这是代码:

var storyId = ... (fetch from a request);
var intStoryId = parseInt( storyId) ;
var arrayOfHigherNumber = function() {
var temp = [];
if ( intStoryId == 5 ) { return temp; }
for ( var i = intStoryId + 1; i <= 5; i++ ) {
temp.push( i.toString() );
}
return temp;
}
collection.bulkWrite([
// This works and is able to delete the particular story_id entry
{ updateOne: {
'filter': {'_id' : ObjectID( docId ) },
'update': { 
'$pull': { 'stories': { 'story_id': storyId } }
}
}},
// This does NOT work. 
{ updateMany: {
'filter': { '_id': ObjectID( docId ), 'story_id': { '$in': arrayOfHigherNumber() } },
'update': {
'$set': { 'stories': { 'story_id': ( parseInt( 'story_id', 10 ) - 1 ).toString() } 
}
}
}}
])

在过去的 24 小时里,我一直在用头撞墙,并尝试了许多方法,包括NumberInt$int$convert,以及更多方法,例如聚合管道,但我无法做到这一点。这似乎很容易完成,但唉!请注意,story_id是一个字符串,因此使用起来并不简单,比如说,$inc运算符。

编辑

安东尼·温兹莱特的回答是正确的。我的处理方式略有不同,仅此而已。

我的方法

collection.findOneAndUpdate(
{ "_id": ObjectID( docId) },
{ "$pull": { "stories": { "story_id": storyId } } },
{ returnOriginal: false }
)
.then( function( story ) {
collection.findOneAndUpdate(
{ "_id" : ObjectID( docId ) },
{ "$set": {
"stories": story.value.stories.map(a => {
if ( parseInt( a.story_id, 10 ) > parseInt( storyId, 10 ) ) {
return { story_id: (parseInt( a.story_id, 10 ) - 1).toString(), objects: a.objects }
} else {
return { story_id: a.story_id , objects: a.objects }
}
})
}}
)
.then( function ( result ) {
response.send( result );
client.close();
})
})

而不是批量查询使用两个操作使用async await

const story = await collection.findOneAndUpdate(
{ "_id" : ObjectID( docId ) },
{ "$pull": { "stories": { "story_id": storyId } }},
{ "new": true }
)
const update = await collection.findOneAndUpdate(
{ "_id" : ObjectID( docId ) },
{ "$set": {
"stories": story.stories.map((a, i) => { if (parseInt(a.story_id) > parseInt(story_id)) return { story_id: parseInt(a.story_id) + 1 }})
}}
)

collection.updateMany({ story_id : { $gte : deletedElementNo } }, { $inc : { story_id: -1 } });

我认为这是您要找的那种东西?

最新更新