2013-08-26 3 views
0

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

{ name: ..., addresses: [...], courses: [ {name: ... , duration: ..., tags[...]} ] }

теги имеет массив String.

Я пытаюсь найти курс, который имеет некоторые теги внутри, как: Java, затмение, распорки и так далее ...

Мой метод поиска выглядит следующим образом:

public BasicDBList coordinates(List tags){

BasicDBObject cmdBody = new BasicDBObject("aggregate", "EducationalInstitution"); 

    List<BasicDBObject> pipeline = new ArrayList<BasicDBObject>(); 

    BasicDBObject projectParams = new BasicDBObject(); 
    projectParams.put("name", 1); 
    projectParams.put("addresses.state", 1); 
    projectParams.put("addresses.locs", 1); 
    projectParams.put("courses", 1); 

    pipeline.add(new BasicDBObject("$project", projectParams)); 
    pipeline.add(new BasicDBObject("$unwind", "$addresses")); 
    pipeline.add(new BasicDBObject("$unwind", "$courses")); 
    pipeline.add(new BasicDBObject("$match", new BasicDBObject("courses.tags", new BasicDBObject("$all", tags)))); 

    cmdBody.put("pipeline", pipeline); 

    return (BasicDBList) getDatastore().getDB().command(cmdBody).get("result"); 
} 

Когда я запускаю это я получаю результаты, как:

{ "_id" : ... , "name" : "X25" , "addresses" : { "state" : "DF" , "locs" : [ -15.806789 , -47.912779]} , "courses" : { "name" : "Microsoft Office Word 2010" , "duration" : 22 , "tags" : [...]}}

{ "_id" : ... , "name" : "X25" , "addresses" : { "state" : "DF" , "locs" : [ -15.806789 , -47.912779]} , "courses" : { "name" : "Microsoft Office Excel 2010" , "duration" : 18 , "tags" : [...]}} 

{ "_id" : ... , "name" : "X25" , "addresses" : { "state" : "DF" , "locs" : [ -15.806789 , -47.912779]} , "courses" : { "name" : "Microsoft Office PowerPoint 2010" , "duration" : 14 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "DF" , "locs" : [ -15.797209 , -47.883596]} , "courses" : { "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "DF" , "locs" : [ -15.797209 , -47.883596]} , "courses" : { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "DF" , "locs" : [ -15.797209 , -47.883596]} , "courses" : { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "PR" , "locs" : [ -25.431803 , -49.279532]} , "courses" : { "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "PR" , "locs" : [ -25.431803 , -49.279532]} , "courses" : { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "PR" , "locs" : [ -25.431803 , -49.279532]} , "courses" : { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "SP" , "locs" : [ -23.574942 , -46.71048]} , "courses" : { "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "SP" , "locs" : [ -23.574942 , -46.71048]} , "courses" : { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "SP" , "locs" : [ -23.574942 , -46.71048]} , "courses" : { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}} 

Что я хочу, это групповые курсы, которые я изучаю по названию образовательного учреждения и адресу. Например: { "_id" : ... , "name" : "X25" , "addresses" : { "state" : "DF" , "locs" : [ -15.806789 , -47.912779]} , "courses" : [{ "name" : "Microsoft Office Word 2010" , "duration" : 22 , "tags" : [...]}, { "name" : "Microsoft Office Excel 2010" , "duration" : 18 , "tags" : [...]}, { "name" : "Microsoft Office PowerPoint 2010" , "duration" : 14 , "tags" : [...]}]}

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "DF" , "locs" : [ -15.797209 , -47.883596]} , "courses" : [{ "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}, { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}, { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}]} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "PR" , "locs" : [ -25.431803 , -49.279532]} , "courses" : [{ "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}, { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}, { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}]} 

{ "_id" : ... , "name" : "ENG" , "addresses" : { "state" : "SP" , "locs" : [ -23.574942 , -46.71048]} , "courses" : [{ "name" : "MS Visio" , "duration" : 0 , "tags" : [...]}, { "name" : "Acrobat Professional" , "duration" : 12 , "tags" : [...]}, { "name" : "Framemaker" , "duration" : 0 , "tags" : [...]}]} 

Я прочитал о $ push и попытаюсь реализовать, но безуспешно. Я попытался добавить BasicDBObject в переменную конвейера и добавить команду cmdBody.

Прошел ли кто-нибудь за аналогичную проблему?

ответ

1

Вы можете использовать $ нажимной оператор вместе с оператором $ группового трубопровода, как это в оболочке:

db.t.aggregate([{$unwind:'$b'},{$unwind:'$c'},{$group:{_id:'$b',cs:{$push:'$c'}}}]) 

В вашем случае в JAVA-то вроде:

pipeline.add(new BasicDBObject("$group", new BasicDBObject(new BasicDBObject("_id", groupParams)).append("courses", new BasicDBObject("$push", "$courses")))); 

Если вы строго вероятно для использования того же формата, который вы описали, вы можете включить в конце шаг $ project, который позволяет переформатировать результирующие документы.

+0

Я просто изменил ваш код на pipeline.add(new BasicDBObject("$group", new BasicDBObject(new BasicDBObject("_id", groupParams)).append("courses", new BasicDBObject("$push", "$courses"))));, потому что в BasicDBObject нет конструктора с 2 параметрами BasicDBObject. В любом случае, это работает! Thx – arthurfnsc

+0

Thx для комментария, я отредактировал код согласно. – attish