обработка ошибок для дубликата ключа в MongoDB

#mongodb #error-handling #indexing

#mongodb #обработка ошибок #индексирование

Вопрос:

у меня есть коллекция в MongoDB. и я создаю уникальный индекс в файле «word».

у меня есть метод, подобный приведенному ниже, для добавления в коллекцию:

 private boolean add(String word, Map<String, Integer> docOccurrence, Map<String, Integer> totalOccurrence) {
    db.requestStart();
    BasicDBObject document = new BasicDBObject();
    document.put(DB_COLLECTION_WORD_CAT_COL_WORD, SQLQueryValidation.validateBeforeWrite(word));
    document.put(DB_COLLECTION_WORD_CAT_COL_DOC_OCCURRENCE, new BasicDBObject(docOccurrence));
    document.put(DB_COLLECTION_WORD_CAT_COL_TOTAL_OCCURRENCE, new BasicDBObject(totalOccurrence));
    try {
        synchronized (LOCK_WRITE) {
            table.save(document, WriteConcern.SAFE);
            //System.out.println(wr.getField("ok"));
        }
    } catch (MongoException e) {
        System.out.println("heh");
        logger.error("Could not insert new row to word_cat : {}", e.getMessage());
        return false;
    }
    return true;
}
  

но если я вставлю повторное слово, я получу эту ошибку!

  Could not insert new row to word_cat : insertDocument :: caused by :: 11000 E11000       duplicate key error index: cat.word_cat_english.$word_1  dup key: {"test_word" }
  

я ожидаю, что это не вызовет проблем, потому что использование .save вместо .insert

я уже использовал Cassandra, и у него есть автоматическая вставка.

как я могу этим управлять?

и в целом, каков наилучший способ обработки ошибок в MongoDB?

Спасибо.

Комментарии:

1. MongoDB «save» обрабатывал значение _id документа. Таким образом, в вашем случае исходный документ будет обновляться только в том случае, если вы установите значение _id на то же значение, которое было вставлено изначально. Одним из возможных способов справиться с этим было бы самостоятельно установить _id в значение WORD, учитывая, что это имеет смысл для вашей модели данных и вариантов использования.

Ответ №1:

Я повторяю ответ zsh выше. Другими словами, как mongo может угадать, пытаетесь ли вы по ошибке вставить дубликаты или пытаетесь обновить существующие данные. Я бы либо:

1) Запустите «выбрать по слову», и если такой документ уже существует — сохраните с его идентификатором

2) Используйте монго upsert: http://docs.mongodb.org/manual/reference/method/db.collection.update /

Просто предупреждение, когда я использовал spring-data-mongo, 2-й подход был более «низкоуровневым» и менее «объектно-ориентированным», например, реализация spring не отправляла события и не выполняла оптимистичные обновления (хотя вы можете перепроверить это, я использовал старую версию).