2015-04-20 5 views
0

Я пытаюсь определить, есть ли способ использовать spring-mongodb (или даже использовать API-интерфейс mongo java), чтобы обновить документ, содержащий список так что элементы списка всегда являются объединением значений, которые были сохранены.Как обновить документ mongo (или spring-mongo), содержащий список

Пусть у меня есть следующие классы (составленные упрощать вещи):

public class Patron { 
    private String name; 
    private String address; 
    private List<Book> booksRead; 
// assume gets/sets 
} 

public class Book{ 
    private String title; 
    private String author; 
// assume gets/sets 
} 

Далее, давайте предположим, что я получаю обновления на только последние книги читать, но я хочу сохранить в БД в полной мере список всех прочитанных книг. Так что я хотел бы сделать, это вставить Patron (with booksRead), если он не существует или обновить их книги. Читайте, если Patron уже существует.

Итак, первый upsert «John Doe» не в сборе, поэтому документ вставляется и выглядит следующим образом:

"_id": ObjectId("553450062ef7b63435ec1f57"), 
"name" : "John Doe" 
"address" : "123 Oak st, Anytown, NY, 13760" 
"booksRead" : [ 
     { 
      "title" : "Grapes of Wrath", 
      "author" : "John Steinbeck" 
     }, 
     { 
      "title" : "Creatures Great and Small", 
      "author" : "James Herriot" 
     } 
] 

Джон перечитывает «Гроздья гнева», а также гласит: «О мышах и Мужчины'. При попытке вставки проходит 2 книги, книги читать, но я хотел бы только вставить «О мышах и людях» в список чтения, так что документ выглядит следующим образом:

"_id": ObjectId("553450062ef7b63435ec1f57"), 
"name" : "John Doe" 
"address" : "123 Oak st, Anytown, NY, 13760" 
"booksRead" : [ 
     { 
      "title" : "Grapes of Wrath", 
      "author" : "John Steinbeck" 
     }, 
     { 
      "title" : "Creatures Great and Small", 
      "author" : "James Herriot" 
     }, 
     { 
      "title" : "Of Mice and Men", 
      "author" : "John Steinbeck" 
     } 
] 

Все, что я пытался, кажется, указывает для того, чтобы отделить вызовы один для вставки и один для обновления. Update.set работает для начальной загрузки (вставка), но заменяет полный список второго обновления. $ addToSet работает над обновлением, но жалуется на попытку вставить в 'non-array' при начальной вставке.

UPDATE:

Это, как представляется, проблема с Спринг-MongoDB. Я могу достичь вышеуказанного с помощью mongo java api calls, он просто терпит неудачу при использовании весенних эквивалентов. (по крайней мере, до spring-data-mongodb 1.6.2)

ответ

0

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

+1

Да, проблема в том, что монго не поддерживает транзакции, вам нужно управлять этим самостоятельно. Поэтому, прежде чем я создам целую многофазную схему commint с блокировкой, я пытаюсь понять, могу ли я использовать возможности upsert mongo –

0

Я думаю, вы могли бы сделать это с помощью оператора addToSet. Вы можете найти документацию на веб-сайте MongoDB в: http://docs.mongodb.org/manual/reference/operator/update/addToSet/#up._S_addToSet

Он используется либо с обновлением (или) findAndModify() методы.

+0

Да, я смог использовать addToSet, пока документ (патрон) для обновления уже существует , Если это не так, я получил ошибку, о которой я упоминал, «не может вставить в не-массив» или что-то подобное. –

+0

фактическое сообщение об ошибке = 'не может применять модификатор $ addToSet для не-массива' –

+0

и комбинировать с upsert = true, чтобы создать массив, если он не существует? – Snorky35

0

Проблема, как представляется, находится в слое Spring. Хотя я получаю ошибки с помощью команды FindAndModify, у меня нет проблемы с $ addToSet с методами mongo DBCollection.findAndModify и DBCollection.update.

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

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