Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure unique item in an array based on specific fields - mongoDB?

In my scenerio, there are authors in a collection, each author has messages and each message of author can has events. Each actor allowed to perform only one kind of action once.

db.people.ensureIndex({messages.messageEvents.eventName: 1, messages.messageEvents.actorId: 1}, {unique: true});

I added index but it has no effect. As you see below, my document has three elements which have "eventName":"vote" and "actorId":"1234" that should be against my constraint.

How to ensure unique item in messageEvents array based on eventName and actorId fields ?

Actually, i need to update the existing item without a second search and update event instead of rejecting it .

{
  "_id": "1234567",
  "authorPoint": 0,
  "messages": [
    {
      "messageId": "112",
      "messageType": "Q",
      "messagePoint": 0,
      "messageEvents": [
        {
          "eventName": "Add",
          "actorId": "1234",
          "detail": ""
        },
        {
          "eventName": "Vote",
          "actorId": "1234",
          "detail": "up"
        },
        {
          "eventName": "Vote",
          "actorId": "1234",
          "detail": "down"
        },
        {
          "eventName": "Vote",
          "actorId": "1234",
          "detail": "cork"
        }
      ]
    }
  ]
}
like image 410
yuceel Avatar asked Apr 30 '12 11:04

yuceel


1 Answers

Mustafa, unique constraints are not enforced within a single array, although they're enforced among documents in a collection. This is a known bug that won't be fixed for a while:

https://jira.mongodb.org/browse/SERVER-1068

There's a workaround, though. Keep your unique index in place, and:

1) Ensure your application does not insert new documents with duplicate values in the array. You can check for uniqueness in your application code before inserting.

2) When updating existing documents use $addToSet instead of $push.

like image 131
A. Jesse Jiryu Davis Avatar answered Nov 16 '22 01:11

A. Jesse Jiryu Davis