2015-09-07 4 views
0

Я с удивлением вижу, что _id не является уникальным индексом. Я предоставляю значения для поля _id, а MongoDB создает индекс в порядке, но он не уникален. Я попытался обновить его (создав новый уникальный индекс в поле _id), но ничего не изменилось. Я тоже не ошибся. Почему это происходит и как я могу сделать уникальный индекс на _id?Почему идентификатор индекса Casbah/MongoDB не уникален?

Версия MongoDB (как указано version()) 3.0.6, версия Casbah 2.8.2, версия Scala 2.11.7.

Мой документ Структура:

{_id=1, firstName=John, lastName=Doe, phoneNum=111-111-1111, active=true, [email protected]}

Индексы, как сбрасывали в журналах (метка времени и т.д. опущены для краткости). Я не уверен, почему каждый индекс печатает дважды, но это проблема для другого вопроса. Для записей, это как я печатаю индексы: collection.indexInfo.foreach { index => logger.debug(s"Index: ${index.toMap}") }

Index: {v=1, key={ "_id" : 1}, name=_id_, ns=akka.users} 
Index: {v=1, unique=true, key={ "phoneNum" : 1}, name=phoneNum_1, ns=akka.users} 
Index: {v=1, unique=true, key={ "email" : 1}, name=email_1, ns=akka.users, sparse=true} 
Index: {v=1, key={ "_id" : 1}, name=_id_, ns=akka.users} 
Index: {v=1, unique=true, key={ "phoneNum" : 1}, name=phoneNum_1, ns=akka.users} 
Index: {v=1, unique=true, key={ "email" : 1}, name=email_1, ns=akka.users, sparse=true} 

ответ

0

Лампочка отправился в моей голове, когда я увидел @ оператор вставки codename44 выше. Оказалось, что для документа в Монго нельзя использовать уникальное поле _id, чтобы обеспечить уникальность, это поле также должно быть типа ObjectId. Моя проблема заключалась в том, что я вставлял поле как String.

У меня теперь проблема, что ни одна из вложений не работает. Ошибок нет, нет нарушений индекса, но документ просто не вставлен. Смотрите мой обновленный код ниже, который всегда входит 2-й случай (writeResult.getN 0):

Edit: Оказалось, что не удалось вставить фактически не удается. Согласно сообщению this SO, драйвер Java всегда возвращает 0 для числа вставленных строк. Поэтому, если не существует исключения, всегда считается, что вставка выполнена успешно.

override def createUser(user: User) = { 
    val dbObj = userToDbObj(user) 

    val result = Try(collection.insert(dbObj, WriteConcern.Safe)) 

    val newUser = user.copy(userId = Some(dbObj.get(USER_ID).toString)) 

    result match { 
    case Success(writeResult) if (writeResult.getN == 1) => Some(newUser) 
    case Success(writeResult) => 
     logger.error(s"Failed to create user: ${newUser}, write result: ${writeResult}."); None 
    case Failure(ex) => logger.error("Failed to create user.", ex); None 
    } 
} 

private def userToDbObj(user: User) = { 
    val builder = MongoDBObject.newBuilder 

    builder += USER_ID -> (user.userId match { 
    case Some(userId) if (ObjectId.isValid(userId)) => logger.info("Using given user id."); new ObjectId(userId) 
    case _ => logger.info("Generating new user id."); new ObjectId() 
    }) 

    builder += (FIRST_NAME.toString -> user.firstName, 
    LAST_NAME.toString -> user.lastName, 
    PHONE_NUM.toString -> user.phoneNum) 

    user.email match { 
    case Some(email) => builder += EMAIL.toString -> user.email.get 
    case _ => 
    } 

    builder.result 
} 
1

В видеообращении Mongo курсы, говорится, что индекс «_id» не помечен как уникальный с помощью команды db.collection.getIndexes(), даже если он является уникальный. Я не могу найти эту информацию в официальной документации.

Если вы хотите быть уверенным, попробуйте добавить другой документ с существующим полем _id.

Моего _id индекс не помечен уникальным:

> db.products.getIndexes() 
[ 
     { 
       "v" : 1, 
       "key" : { 
         "_id" : 1 
       }, 
       "name" : "_id_", 
       "ns" : "test.products" 
     } 
] 

Добавить существующий индекс и получить Дублировать ключевую ошибку:

> db.products.insert({ "_id" : ObjectId("55ed6ccc20a18b075ba683b2")}) 
WriteResult({ 
     "nInserted" : 0, 
     "writeError" : { 
       "code" : 11000, 
       "errmsg" : "E11000 duplicate key error index: test.products.$_id_ dup key: { : ObjectId('55ed6ccc20a18b0 
75ba683b2') }" 
     } 
}) 
+0

Я проверил перед публикацией, это позволило вставить. Я выяснил эту проблему, см. Мой ответ ниже. Я собираюсь поддержать ваш ответ как полезный, но не правильный. –

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