Как обеспечить уникальный элемент в массиве на основе определенных полей - mongoDB?

В моем сценарии есть авторы в коллекции, каждый автор имеетmessages и каждое сообщение автора может иметьevents, Каждому актеру разрешено выполнять только один вид действия один раз.

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

Я добавил индекс, но это не имеет никакого эффекта. Как вы видите ниже, мой документ имеет три элемента, которые имеют"eventName":"vote" а также"actorId":"1234" это должно быть против моего ограничения.

Как обеспечить уникальный предмет вmessageEvents массив на основеeventName а такжеactorId поля?

На самом деле, мне нужно обновить существующий элемент без второго поиска и обновить событие, а не отклонить его.

<code>{
  "_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"
        }
      ]
    }
  ]
}
</code>

Ответы на вопрос(1)

Решение Вопроса

уникальные ограничения не применяются в одном массиве, хотя они применяются среди документов в коллекции. Это известная ошибка, которая не будет исправлена некоторое время:

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

Но есть обходной путь. Держите свой уникальный индекс на месте, и:

1) Убедитесь, что ваше приложение не вставляет новые документы с дублирующимися значениями в массив. Вы можете проверить уникальность кода своего приложения перед вставкой.

2) При обновлении существующих документов используйте $ addToSet вместо $ push.

 A. Jesse Jiryu Davis07 янв. 2015 г., 21:52
@ OuwenHuang Я думаю, что это отдельный вопрос, я бы задал его отдельно, вместо того, чтобы комментировать этот принятый ответ.
 yuceel02 мая 2012 г., 12:59
Спасибо за Ваш ответ. Вы правы. Я уже изменил свое представление документа и применил обходной путь после нескольких исследований. Жаль, что не было легкого пути Это имеет стоимость, и это может вызвать сложность кода:
 Ouwen Huang07 янв. 2015 г., 03:55
Даже с $ addToSet, допустим, что мы выдвинули что-то вроде {userId: 1234, voice: obama}, $ addToSet не остановил бы {userId: 1234, voice: romney}, как бы вы убедились, что набор объектов обеспечивает уникальность только для userId?
 Alexis Tyler04 февр. 2017 г., 06:57
@ A.JesseJiryuDavis есть шанс, что вы сможете обновить этот ответ на 2017 год.
 Ouwen Huang07 янв. 2015 г., 21:58
Да, ты прав, моя ошибка.

Ваш ответ на вопрос