如果基于特定字段,MongoDB将项目添加到文档数组中(如果尚不存在)

时间:2019-05-03 18:26:59

标签: javascript node.js mongodb mongoose

我有一个像这样的MongoDB文档:

    "_id" : ObjectId("5ccb4067d0c24b35d4cbb51e"),
    "title" : "Sharing test 1",
    "content": "Test Content",
    "creator" : ObjectId("5c715d627adcfb7980c5d4c2"),
    "createdAt" : ISODate("2019-05-03T00:39:27.594+05:30"),
    "lastUpdatedAt" : ISODate("2019-05-03T00:39:27.609+05:30"),
    "sharingInfo" : [ 
        {
            "_id" : ObjectId("5c715d627adcfb7980c5d6c2"),
            "accessType" : "edit"
        }, 
        {
            "_id" : ObjectId("5c72acf12f63693410f2ae1a"),
            "accessType" : "view"
        }
    ]

我要在字段sharingInfo中以下述行为插入文档:

如果具有相同值的_id字段已经存在,则更新accessType的值,否则创建一个新的新条目。

我将尝试用两个例子来解释。

示例1

假设我正在尝试插入这样的文档:

  {
    "_id" : ObjectId("5c72acf12f63693410f2ae1a"),
    "accessType" : "edit"
  }

由于此_id已经存在,因此生成的sharingInfo应该像:

    "sharingInfo" : [ 
        {
            "_id" : ObjectId("5c715d627adcfb7980c5d6c2"),
            "accessType" : "edit"
        }, 
        {
            "_id" : ObjectId("5c72acf12f63693410f2ae1a"),
            "accessType" : "edit"
        }
    ]

示例2

假设我正在尝试插入这样的文档:

  {
    "_id" : ObjectId("5ccb4070d0c24b35d4cbb520"),
    "accessType" : "view"
  }

由于此_id尚不存在,因此生成的sharingInfo应该如下:

    "sharingInfo" : [ 
        {
            "_id" : ObjectId("5c715d627adcfb7980c5d6c2"),
            "accessType" : "edit"
        }, 
        {
            "_id" : ObjectId("5c72acf12f63693410f2ae1a"),
            "accessType" : "edit"
        },
        {
            "_id" : ObjectId("5ccb4070d0c24b35d4cbb520"),
            "accessType" : "view"
        }
    ]

我遇到了运算符$addToSet,但是它比较了整个文档,我无法根据特定字段_id对其进行比较

如果我可以根据某些条件删除重复副本,但同样可以使用,但是我发现dropDups在MongoDB的最新版本中不再可用。

当我想用某些数据更新sharingInfo时,我以对象格式的数组接收数据: 例如:

[
  {
    "_id" : ObjectId("7d72acf12f63693410f2ae1b"),
    "accessType" : "edit"
  },
  {
    "_id" : ObjectId("8acb4070d0c24b35d4cbb521"),
    "accessType" : "view"
  }
]

如果我尝试执行$set操作,则sharingInfo的全部内容将被新数据替换。

这里的想法是最大程度地减少API请求的数量,如果某人想要使用多个数据更新共享信息,则他/她可以发送一个带有一组要更新为有效负载的对象的API请求。

我正在使用猫鼬对数据进行建模。

有没有有效的方法来完成整个操作?

我可以在数据库中执行多次读写操作,但是效率很低,不要这么做。

这是一个更新,如果存在的话,否则插入文档数组中

PS:我是MongoDB的新手。

谢谢。

2 个答案:

答案 0 :(得分:0)

通常,您将使用猫鼬找到要更新的文档,适当地更新其sharedInfo数组,然后保存该文档。无论如何,我不知道要执行原子操作中所描述的事情。

答案 1 :(得分:0)

而不是将整个对象添加到sharingInfo数组中...

将其保存在不同的集合中,并在_id的帮助下将其放入sharingInfo中的$addToSet

现在是view还是edit,您只需使用_id来更新该颗粒数据。 可以在populated的帮助下进行.populate(fieldName)的引用...有关更多信息,请参阅猫鼬文档。

访问:Mongoose - Populate