gpt4 book ai didi

Mongoose - Increment a value inside an array of objects(Mongoose-在对象数组中增加一个值)

转载 作者:bug小助手 更新时间:2023-10-25 19:56:17 25 4
gpt4 key购买 nike



I am having hard time figuring out how to increment a value in an object within an array

我很难弄清楚如何在数组中的对象中递增一个值



For instance I have this document based on Poll schema:

例如,我有一个基于轮询模式的文档:



{
"_id": "584b2cc6817758118e9557d8",
"title": "Number of Skittles",
"description": "Test1",
"date": "Dec 9, 2016",
"__v": 0,
"labelOptions": [
{
"Bob": 112
},
{
"Billy": 32
},
{
"Joe": 45
}
]
}


Using express, I am able to get this far:

使用Express,我能够走到这一步:



app.put('/polls/:id', function(req, res){
let id = req.params.id;
let labelOption = req.query.labelOption;
Poll.findOneAndUpdate(
{'_id' : id},
{$inc: {`labelOptions.$.${labelOption}`: 1 }},
function(err){
console.log(err)
})


where labelOption is the one that I would like to increment its value

其中,LabelOption是我希望递增其值的选项



To be more concise, I am having trouble transversing inside the document.

更简洁地说,我在横切文档内部时遇到了困难。


更多回答
优秀答案推荐

It is not possible to directly increment the value in the .find query if labelOptions is an Array of Object. To make it easier, you should change the labelOptions type from Array of Objects to Object:

如果labelOptions是对象数组,则不可能在.find查询中直接递增该值。为方便起见,应将labelOptions类型从数组对象更改为对象:



"labelOptions": {
"Bob": 112,
"Billy": 32,
"Joe": 45
};


Also consider using .findByIdAndUpdate instead of .findOneAndUpdate if you are querying by the document's _id. And then, you can achieve what you want by:

如果按文档的_id进行查询,还可以考虑使用.findByIdAndUpdate而不是.findOneAndUpdate。然后,您可以通过以下方式实现您想要的:



Poll.findByIdAndUpdate(
id,
{$inc: {`labelOptions.${labelOption}`: 1 }},
function(err, document) {
console.log(err);
});


UPDATE: If you are persistent on using Array of Objects for labelOptions, there is a workaround:

更新:如果你坚持使用对象数组的labelOptions,有一个解决方案:



Poll.findById(
id,
function (err, _poll) {

/** Temporarily store labelOptions in a new variable because we cannot directly modify the document */
let _updatedLabelOptions = _poll.labelOptions;

/** We need to iterate over the labelOptions array to check where Bob is */
_updatedLabelOptions.forEach(function (_label) {

/** Iterate over key,value of the current object */
for (let _name in _label) {

/** Make sure that the object really has a property _name */
if (_label.hasOwnProperty(_name)) {

/** If name matches the person we want to increment, update it's value */
if (_name === labelOption) ++_label._name;
}
}
});

/** Update the documents labelOptions property with the temporary one we've created */
_poll.update({labelOptions: _updatedLabelOptions}, function (err) {

console.log(err);
});
});


There is another way to do this which allows a more flexible document model. If you add a field to your object like:

有另一种方法可以做到这一点,它允许更灵活的文档模型。如果将字段添加到对象中,如下所示:


{
"_id": "584b2cc6817758118e9557d8",
"title": "Number of Skittles",
"description": "Test1",
"date": "Dec 9, 2016",
"__v": 0,
"labelOptions": [
{
"name": "Bob",
"number": 112
},
{
"name": "Billy",
"number": 32
},
{
"name": "Joe"
"number": 45
}
]
}

Then you can do:

然后,您可以执行以下操作:


app.put('/polls/:id', function(req, res){
let id = req.params.id;
let labelOption = req.query.labelOption;
Poll.findOneAndUpdate(
{
'_id' : id,
'labelOptions.name': labelOption
},
{$inc: {
"labelOptions.$.number": 1
}},
function(err){
console.log(err)
})
});


People solved it but, if you use that for if element in array doesnt exits, a solution:

人们解决了这个问题,但是,如果您使用它来表示数组中的元素不存在,则会有一个解决方案:


            app.put('/polls/:id', async function (req, res) {
let id = req.params.id;
let labelOption = req.query.labelOption;
const exits = await Poll.exists({ _id: id, "labelOptions.name": labelOption });

if (exits)
await Poll.updateOne(
{ _id: id, "labelOptions.name": labelOption },
{
$inc: {
"labelOptions.$.number": 1
}
}
);
else
await Poll.updateOne({ _id: id }, {
$push: {
labelOptions: {
name: labelOption,
number: 1
}
}
});

});


更多回答

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com