Inspired by another question, suppose I have documents that contain an array of events, where each event has 3 fields: eventName
, actorId
, and detail
:
{
_id: ObjectId("5a934e000102030405000000"),
date: ISODate("2022-06-03T00:00:00.000Z"),
events: [
{
eventName: "Add",
actorId: "1",
detail: "new actor"
},
{
eventName: "Vote",
actorId: "2",
detail: "up"
},
{
eventName: "Vote",
actorId: "3",
detail: "down"
},
{
eventName: "Vote",
actorId: "4",
detail: "cork"
}
]
}
I want to add new items into a specific document (according to its _id
), but each item can be added only if none of the existing items as the same eventName
and actorId
unique combination.
For example trying to add:
[
{
eventName: "Add",
actorId: "3",
detail: "action"
},
{
eventName: "Vote",
actorId: "2",
detail: "up"
},
{
eventName: "Vote",
actorId: "5",
detail: "up"
}
]
Will result in adding only the 1st and 3rd item, as a combination of eventName: "Vote"
and actorId: "2"
already exists in the events
array.
2
Answers
Since monogDB version 4.2, this can be done using an update with aggregation pipeline:
$addFields
with newData to add and create a newkeys
field that contains the existing unique keys concatanted.$filter
thenewData
to include only items with keys that are not in the original array keys.$concatArrays
:events
and the filterednewData
array.Playground example
Here is a way of performing the update operation using Updates With Aggregation Pipeline feature (requires MongoDB v4.2 or higher). The variable
NEW_EVENTS
represents the new data that is input as an array of documents (e.g.,[ { "eventName" : "Vote", "actorId" : "5", "detail" : "up" }, { ... }, ... ]
).