如何从深度嵌套的文档中 $pull (mongoose)

Posted

技术标签:

【中文标题】如何从深度嵌套的文档中 $pull (mongoose)【英文标题】:How To $pull From Deeply Nested Document (mongoose) 【发布时间】:2021-03-29 02:23:54 【问题描述】:

我需要从位置数组中删除一个位置对象。它嵌套很深。我遵循猫鼬文档,但我的尝试没有奏效:

lists = [
  "listName": "Test",
  "_id": "8d55f0afe545a0178c320706",
  "listId": "5fd9a3bef6c39b2f9c4df65b",
  "date": "12/15/2020",
  "dueDate": "2020-11-18",
  "items": [
    
      "itemNumber": 123,
      "description": "item123",
      "onHand": 60,
      "_id": "13dd1f26ecd2baeb61b3b455",
      "locations": [
        
          "locationName": "loc1",
          "count": 10,
          "_id": "50a2c969465ba8010bd48977"
        ,
        
          "locationName": "loc2",
          "count": 20,
          "_id": "51c2f1d25311dc8fabdbf604a59b"
        ,
        
          "locationName": "Loc3",
          "count": 30,
          "_id": "7cb0c1f51a91c384846d65f8b2ae"
        
      ]
    ,
    more lists

尝试:

router.post("/lists/deleteLoc", (req, res) => 
      const 
        listId,
        list_id,
        item_id,
        location_id
       = req.body;
      List.updateOne(
            "lists.listId": listId,
            "lists._id": list_id
          , 
            $pull: 
              "lists.$.items": 
                locations: 
                  $elemMatch: 
                    _id: location_id
                  )
                .then(() => res.json(
                  msg: "location removed"
                ))
                .catch((err) => res.status(400).json(
                  msg: "Error: " + err
                ));
              );

如果请求 location_id 是“7cb0c1f51a91c384846d65f8b2ae”,它应该从数组中删除最后一个位置。期望的结果:

lists = [
  "listName": "Test",
  "_id": "8d55f0afe545a0178c320706",
  "listId": "5fd9a3bef6c39b2f9c4df65b",
  "date": "12/15/2020",
  "dueDate": "2020-11-18",
  "items": [
    
      "itemNumber": 123,
      "description": "item123",
      "onHand": 60,
      "_id": "13dd1f26ecd2baeb61b3b455",
      "locations": [
        
          "locationName": "loc1",
          "count": 10,
          "_id": "50a2c969465ba8010bd48977"
        ,
        
          "locationName": "loc2",
          "count": 20,
          "_id": "51c2f1d25311dc8fabdbf604a59b"
        
      ]
    ,
    more lists

我已经尝试了基本上所有的变体,但都没有奏效。

我也不确定发出 router.post 或 axios.post 删除请求是否正确。这应该是 axios.delete 和 router.delete 吗?

【问题讨论】:

【参考方案1】:

我已经在我的一个类似数据库中尝试过这个并且成功了!

List.updateOne( "listId": yourListId ,
        
            '$pull': 
                'items.$[item].locations':  "_id": yourLocationId 
            
        , 
        "arrayFilters": [
            
                "item._id": yourItemId
            
        ]
    , function (err) 
        if (err) 
            res.json(err)
         else 
            res.json( message: "Updated" )
        
    )


您必须从要删除的对象中放入数据库中的值。

所以如果你想删除对象

“位置名称”:“Loc3”

你应该使用

var yourListId = "5fd9a3bef6c39b2f9c4df65b";
var yourItemId = "13dd1f26ecd2baeb61b3b455";
var yourLocationId = "7cb0c1f51a91c384846d65f8b2ae";

试试看!

【讨论】:

你是个天才!谢谢你。它奏效了,我从数组过滤器中学到了一些有价值的东西!

以上是关于如何从深度嵌套的文档中 $pull (mongoose)的主要内容,如果未能解决你的问题,请参考以下文章

mongoose:使用$ pull删除嵌入式文档数组中的值(MongoDB 3.4版本)

从嵌套数组mongodb中删除元素

从嵌套数组mongodb中删除元素

如何使用 SwiftyJSON 从深度嵌套的 JSON 字典中获取字符串 [重复]

MongoDB updateOne($pull) 匹配一个文档,但没有从数组中删除它

MongoDB updateOne($pull) 匹配一个文档,但没有从数组中删除它