2012-04-30 2 views
17

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

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

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

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

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

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

ответ

19

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

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

Там обходной путь, хотя. Сохраните свой уникальный индекс на месте и:

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

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

+0

Спасибо за ваш ответ. Ты прав. Я уже изменил представление своего документа и применил обходное решение после нескольких исследований. Хотелось бы, чтобы был простой способ. Это может стоить, и это может вызвать сложность кода :( – yuceel

+1

Даже с $ addToSet, скажем, у нас что-то было введено как {userId: 1234, vote: obama}, $ addToSet не остановит {userId: 1234, vote: romney }, как бы вы могли убедиться, что набор объектов обеспечивает уникальность только для userId? –

+0

@OuwenHuang Я думаю, что это отдельный вопрос, я бы попросил его отдельно, вместо того чтобы комментировать этот принятый ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^