19

在我的场景中,集合中有作者,每个作者都有messages,作者的每条消息都可以有events。每个演员只允许执行一种动作一次。

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

我添加了索引,但没有效果。正如您在下面看到的,我的文档包含三个元素,它们具有"eventName":"vote"并且"actorId":"1234"应该违反我的约束。

如何messageEvents根据eventNameactorId字段确保数组中的唯一项?

实际上,我需要在没有第二次搜索和更新事件的情况下更新现有项目,而不是拒绝它。

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

1 回答 1

24

Mustafa,唯一约束不在单个数组中强制执行,尽管它们在集合中的文档之间强制执行。这是一个已知的错误,暂时不会修复:

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

不过,有一个解决方法。保留您的唯一索引,并且:

1) 确保您的应用程序不会在数组中插入具有重复值的新文档。您可以在插入之前检查应用程序代码中的唯一性。

2) 更新现有文档时使用 $addToSet 而不是 $push。

于 2012-04-30T16:05:16.873 回答