1

我試圖找出如何切換布爾值的「活動」從true到false或false到真基於文檔中存在的值。所以如果它是真的,將它改爲假,如果它是假的,則將其改爲true。示例數組。以編程方式切換布爾值與Mongodb本機驅動

[{ _id: 59cb78434436be173e038aaa, active: true, title: 'One' }, 
{ _id: 59cb78434436be173e038aab, active: false, title: 'Two' }, 
{ _id: 59cb78434436be173e038aac, active: false, title: 'Three' }] 

const todos = db.collection('todos'); 

const active = !active; 
await todos.findOneAndUpdate({ _id: ObjectID(args.id) }, 
{ $set: { active: active } }, function(err, doc) { 
       if (err) { 
        throw err; 
       } else { 
        console.log('Updated'); 
       } 
      }); 

我無法通過將true或false傳遞到活動{ $set: { active: true }}直接設置此。我將如何測試該值並返回相反的結果?

感謝

回答

1

目前存在的MongoDB沒有$撥動操作,因此不可能做出這樣的開關操作原子。 但是這種功能有一些解決方法。 首先你需要用數字替換你的布爾值。 然後,不要試圖用相反的值替換它,你應該每次都增加它。

todos.findOneAndUpdate({_id: ObjectId(args.id)}, {$inc:{ active: 1}}); 

所以你看,每次這將是$加1,這意味着它總是開關將從偶數奇數。

下一步是修改你的「得到」查詢這樣:

todos.find({'active' : { '$mod' : [ 2, 1 ] }); 

這將返回所有的文件現在在哪裏「活動」字段是奇數,你可以考慮像爲例如,反之亦然。

+0

感謝@artem抽空回答。該解決方案的工作儘可能findOneAndUpdate()。我不需要$ mod b/c graphql正在處理這個問題,但我很高興知道它。最後,按照你的建議來做,需要我修改一個模式字段,從布爾到str,所以我去了'''const todos = db.collection('todos'); const oldStatus = await todos.findOne({_id:ObjectID(args.id)}); const newStatus =!oldStatus.active; await todos.findOneAndUpdate({_id:ObjectID(args.id)},{$ set:{active:newStatus}}); return await todos.find()。toArray();'''有沒有更好的方法來做到這一點? – idkjs

+0

爲什麼字符串而不是數字?我其實並不清楚你最終選擇了什麼解決方案? –

+0

通過查詢獲取我想要的字段todo.active。創建一個新的var設置爲字段的切換值,newValue =!todo.active。然後用新值更新原始文檔。不是原子的,還有兩次往返,所以我希望可能有另一種方法來解決這個問題。 – idkjs