尝试删除按userId和listName过滤的子文档,然后删除与restaurantId匹配的项目(不是mongo中的对象ID)。我尝试使用findOneAndUpdate,update,findOne和回调进行操作的多种方法,但均失败了。我开始认为我现在在钻错兔子孔。我将在下面发布我尝试过的所有方法。也许我在想这个太难了。请让我知道是否有删除子文档元素的简单方法!
object.e.g。
{
"userId": 1,
"lists": [
{
"listName": "My Favorites 1",
"items": [
{
"restaurantId": "abcdeqwer",
"cachedAttr": {
"name": "Restaurant1",
"latitude": 100,
"longitude": 100
}
},
{
"restaurantId": "xdpiqweradfaq",
"cachedAttr": {
"name": "Restaurant2",
"latitude": 100,
"longitude": 100
}
}
]
},
{
"listName": "My Favorites 2",
"items": [
{
"restaurantId": "qwerasdfzxcv",
"cachedAttr": {
"name": "Restaurant3",
"latitude": 200,
"longitude": 200
}
},
{
"restaurantId": "xdpiqweradfaq",
"cachedAttr": {
"name": "Restaurant4",
"latitude": 200,
"longitude": 200
}
}
]
}
]
}
基本上给了这个对象,我想用restaurantId:abcdeqwer
删除一个项目。这将从列表嵌套在listName下的items数组中删除item对象。
因此,我首先使用userId进行过滤以获取正确的对象,然后还添加listName以找到正确的项目数组以找到item.restaurantId。我以点符号认为,这应该真的很容易,但我离制作此api还差得远。
我尝试过的以下方法均无效。任何建议将不胜感激。
路由器试用1:
router.delete('/bookmarks', async (req, res) => {
const {listName, restaurantId} = req.body
if (!restaurantId) {
return res
.status(422)
.send({error: 'You must provide a list name.'})
}
try {
Bookmark.findOneAndUpdate({'userId': req.user._id, 'lists.listName': listName}, {
$pull: {
items: {"items.restaurantId": restaurantId},
},
}, {new: true}, (err, doc) => {
if (err) {
console.log(err)
} else {
console.log(doc)
res.send(doc)
}
})
} catch (e) {
console.log(e)
}
})
路由器试用2:
Bookmark.update(
{'userId': req.user._id},
{$pull: {"lists." + pos + ".items.$[item]": }},
{
multi: true,
arrayFilters: [{"list.listName": listName}, {"item.restaurantId": restaurantId}],
new: true,
},
(err, doc) => {
if (err) {
console.log(err)
} else {
console.log(doc)
res.send(doc)
}
})
路由器试用3
Bookmark.update(
{'userId': req.user._id},
{$pull: {"lists.$[list].items.$[item]": null}},
{
multi: true,
arrayFilters: [{"list.listName": listName}, {"item.restaurantId": restaurantId}],
new: true,
}
, (err, doc) => {
if (err) {
console.log(err)
} else {
console.log(doc)
res.send(doc)
}
})
路由器试用4
router.delete('/bookmarks', async (req, res) => {
const {listName, restaurantId} = req.body
if (!restaurantId) {
return res
.status(422)
.send({error: 'You must provide a list name.'})
}
try {
const pos = await Bookmark.findOne({'userId': req.user._id}, async (err, doc) => {
if (err) {
console.log(err)
} else {
let listPosition = await Bookmark.aggregate([
{$project: {"idx": {"$indexOfArray": ["$lists.listName",listName]}}}
]);
listPosition = listPosition[0].idx
// const items = doc.lists[listPosition].items
// items.pull({restaurantId})
// const removed = lists[listPosition].items.pull({restaurantId})
// doc.lists.set(listPosition, lists[listPosition])
// doc.set(`lists.${listPosition}.items`, items)
// const list = doc.lists.pull(listPosition)
// const result = list.items.pull({restaurantId})
// doc.lists[listPosition[0].idx].items = doc.lists[listPosition[0].idx].items
// doc.lists = doc.lists
// console.log("result: ", result)
// doc.lists.push(list)
// doc.save()
// console.log(doc)
// res.send(doc)
return listPosition
}
})