2015-02-09 3 views
0

У меня есть структура вроде этого:UpdateOperations встроенный массив

{ 
    _id: 123, 
    bs: [ 
    { 
     _id: 234, 
     cs: [ 
     { 
      _id: 456, 
      ds : [ 
      { 
       _id: 678, 
       emails[ 
       "[email protected]" 
       ] 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

Мои занятия в морфий, кажется, как этот

@Entity 
public class A { 

    @Id 
    private ObjectId id; 

    @Embedded 
    private List<B> bs; 
} 

public class B { 

    private ObjectId id; 

    @Embedded 
    private List<C> cs; 
} 

public class C { 

    private ObjectId id; 

    @Embedded 
    private List<D> ds; 
} 

public class D { 

    private ObjectId id; 

    @Embedded 
    private List<String> emails; 
} 

То, что я пытаюсь сделать, это вставить электронную почту внутри встроенный массив с морфием без извлеките весь элемент A и используйте updateFirst.

Это запрос, я пытаюсь выполнить

Query<Event> query = this.basicDAO.createQuery(); 
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID)); 
query.criteria("bs.cs.id").equal(new ObjectId(cID)); 
query.criteria("bs.cs.ds.id").equal(dID); 

UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.$.emails", email); 

this.basicDAO.update(query, updateOps); 

Я также прочитал об этом посте Update an item in an array that is in an array с сказал, что

$ оператор не работает «с запросами, пересекающими вложенные массивы».

Так что я пытался что-то вроде:

D d = new D(dID); 
C c = new C(new ObjectId(cID)); 

Query<Event> query = this.basicDAO.createQuery(); 
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID)); 
query.field("bs.cs").hasThisElement(c); 
query.field("bs.cs.ds").hasThisElement(d); 

UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.emails", email); 

this.basicDAO.update(query, updateOps); 

Однако он по-прежнему не работает. Любая идея, как решить это? Сообщение об ошибке, которое я получаю, не может использовать деталь ... для поперечного перемещения элемента

+0

Другое дело, что я нашел и мог быть связан с моей проблемой. Morphia не хранит пустые списки Java. Поэтому, когда я пытаюсь вставить элемент в пустой массив, который я сохраняю ранее, для Morphia это то же самое, что и не хранить список, список ответов является нулевым, а не пустым списком, поэтому будет установлено новое значение в нулевом значении в ошибке – arthurfnsc

+0

Вы можете использовать оператор позиционного соответствия '$' для соответствия нескольким уровням вложенных массивов. Это часть причины, по которой вам следует избегать вложенных массивов в вашей схеме. Какая польза от этой схемы? Что означают разные поля? – wdberkeley

+0

Я не могу дать все детали проекта, но давайте сделаем эту аналогию: представьте, что я могу создать событие (класс A), которое может иметь кучу выпусков (класс B) для каждого издания, может иметь кучу тем (класс C) и каждая тема может иметь кучу лекций (класс D). В конце издания события я хочу, чтобы люди голосовали в своей предпочитаемой лекции. Это не моя модель, это просто аналогия. Моя проблема может быть понята как обновление голосов лекции из темы в выпуске события. Это не идеальная аналогия, но я думаю лучше, чем A, B, C и D – arthurfnsc

ответ

1

На основании вашего варианта использования в режиме ожидания, я думаю, вы должны «инвертировать» вашу схему. Каждый документ будет представлять собой lecture и будет помечено с его theme, edition и event:

{ 
    "_id" : ObjectId("54da1ff0a9ce603a239c3075"), 
    "event" : "X0004", 
    "edition" : "A0002, 
    "theme" : "RT0005", 
    "votes" : 22 
} 

event, edition и theme могут быть какие-то идентификаторы, и могут быть ссылки на event, edition и theme документы в других коллекциях. Для того, чтобы проголосовать за конкретной лекции, просто обновить его _id:

db.test.update({ "_id" : ObjectId("54da1ff0a9ce603a239c3075") }, { "$inc" : { "votes" : 1 } }) 

Пока я не знаю, ваши полные требования, я считаю, что это лучше, базовая конструкция учитывая ваш пример случай использования.

+0

одной из моих проблем является то, что тема выпуска событий и лекции являются просто аналогами. В моей реальной проблеме эти сущности более сложны, чем это. Мне нужно сохранить почту для будущих запросов, а просто увеличить ее значение. Моя проблема по-прежнему заключается в том, как перекрестно несколько массивов в операции обновления в Morphia. Thxs в любом случае – arthurfnsc

+0

Я могу вам только помочь в неполной аналогии с вашим прецедентом. Некоторые из идей в моем ответе действительны для более сложных ситуаций, чем аналогия - вам может потребоваться изменить операции или немного усложнить ситуацию. Одно можно сказать наверняка, однако, вам будет крайне сложно работать с 4-глубинным гнездом массивов. – wdberkeley

+0

Вы даете мне отличную идею, как избежать 4-глубоких массивов гнезд. Я не знал об этом монго «ограничение», поэтому я изменю свою модель. Thx @wdberkeley – arthurfnsc

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