2014-10-10 4 views
0

мне нужно задать вопрос о вложенном состоянии объекта в моем документе, который выглядит следующим образом:Выполнение запросов вложенных объектов в SpringData MongoDb

{ 
    "_id" : ObjectId("5437248f2dfbc82fcafa9733"), 
    "_class" : "conference.Speaker", 
    "speakerId" : NumberLong(0), 
    "name" : "John Doe", 
    "talks" : [{ 
     "talkId" : NumberLong(0), 
     "when" : ISODate("2014-10-17T15:00:00Z"), 
     "title" : "Stuff" 
    }] 
} 

Этот документ выглядит хорошо, и он генерируется из 2-х классов, Speaker и Talk, когда ни один из них не имеет аннотаций, а первый имеет список латтеров как свойство.

Что мне нужно - это список переговоров с определенным именем. Вот что я Тринг делать:

BasicQuery query = new BasicQuery("{'talks.title' : 'Stuff'}"); 

Это терпит неудачу с org.springframework.data.mapping.model.MappingException: Invalid path reference talks.title! Associations can only be pointed to directly or via their id property!

Я предполагаю, что это не может использовать свойство Id (поскольку объект Talk не имеет его собственный идентификатор), и у меня есть не знаю, что «можно указать прямо».

Что случилось с моим запросом и/или отображением?

+0

Я думаю, это потому, что ** переговоры ** является массивом. Для прямого указания это должно быть 'talks.index.title' (index = 0, 1, ...) - конечно, этот стиль не соответствует вашим ожиданиям. Другой способ: «Запрос запроса = новый запрос(). AddCriteria (Criteria.where (« talks.title »). Is (« Stuff »));'. Не уверен, что это то, что вы хотите. – Wizard

ответ

1

Относительно ошибки вам нужно будет предоставить более подробную информацию: точный вызов, который выдает ошибку, версию SpringData, версию MongoDB.

Запрос, который вы построили, выглядит нормально, но он не вернет Talk объектов, но вместо этого вернет Speaker объекты, имеющие хотя бы один разговор 'Stuff'.

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

db.talks.find({"talks.title":"Stuff"}, { talks: { $elemMatch: { title: "Stuff" } } }) 

Если вы хотите все переговоры, соответствующие названия вы» придется использовать агрегацию:

db.talks.aggregate(
     // match only speaker with 'Stuff talks' 
     { $match : { 
      "talks.title": "Stuff" 
     }}, 
     { $unwind : "$talks" }, 
     { $match : { 
      "talks.title": "Stuff" 
     }}, 
     // projection (only talks fields?) 
    ) 
Смежные вопросы