2015-09-18 7 views
2

Здесь ниже я структура документа составлены следующим образом:Mgo Как найти вложенный документ внутри вложенных массивов?

type MIS_Course struct { 
    ID bson.ObjectId `bson:"_id,omitempty"` 
    Name string  `bson:"crse_name"` 
} 

type MIS_Department struct { 
    ID  bson.ObjectId `bson:"_id,omitempty"` 
    Name string  `bson:"dept_name"` 
    Courses []MIS_Course `bson:"crse_list"` 
} 

type MIS_School struct { 
    ID   bson.ObjectId `bson:"_id,omitempty"` 
    Name  string   `bson:"school_name"` 
    Departments []MIS_Department `bson:"dept_list"` 
} 

И когда инициализируется, я бы «Школа ABC» в море школ, содержащих то, что выглядит, как показано ниже:

{ 
    "_id" : ObjectId("55fbb522022aae7b3a000003"), 
    "school_name" : "School ABC", 
    "dept_list" : [ 
     { 
      "dept_name" : "Department A", 
      "crse_list" : [ 
       { 
        "crse_name" : "Class A" 
       }, 
       { 
        "crse_name" : "Class B" 
       }, 
      ] 
     } 
    ] 
} 

часами я не мог найти решение, которое эффективно работает по предоставленным school_name, dept_name и crse_name:

нАЙДИТЕ dept_list из school_name> найти crse_list от dept_name> найти crse_name

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

Я попытался код, такой как

result := MIS_School{} 

err := database.C("schools").Find(bson.M{"school_name": school}).Select(
bson.M{"dept_list": bson.M{"$elemMatch": bson.M{"dept_name": dept}}}).Select(
bson.M{"crse_list": bson.M{"$elemMatch": bson.M{"crse_name": crse}}}).One(&result) 

Но это не сработало, так как Выбор проекции не могут быть соединены в ГГО (?)

Я прочитал где-то, что MongoDB не имеет возможность прямого извлечения документов, вложенных в массивы, глубже 1-2 уровней (получение документа C внутри массива B внутри массива A). Это правда? Как мне решить эту проблему?

Спасибо!

ответ

1

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

Для достижения того, что, по-видимому, вы пытаетесь сделать, вы можете использовать структуру агрегации для управления этими вложенными объектами произвольными способами.

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

pipeline := []bson.M{ 
      {"$match": bson.M{"school_name": school}}, 
      {"$unwind": "$dept_list"}, 
      {"$unwind": "$dept_list.crse_list"}, 
      {"$match": bson.M{ 
        "dept_list.dept_name": dept, 
        "dept_list.crse_list.crse_name": crse, 
      }}, 
    } 
    iter := coll.Pipe(pipeline).Iter() 

Вы можете использовать полученный итератор так же, как использовать итераторы из Находки.

Для этого трубопровода, в результате объекты будут выглядеть следующим образом:

bson.M{ 
      "_id":"...", 
      "dept_list": bson.M{ 
        "dept_name": "Department A", 
        "crse_list": bson.M{ 
          "crse_name": "Class B", 
        } 
      }, 
      "school_name":"School ABC", 
    } 

Вы можете изменить форму результирующего объекта произвольным образом, хотя. Взгляните на документацию aggregation framework для получения более подробной информации.

+0

Хм .... это работает, но скажем, resp: = bson.М {} \t \t \t database.C ("школы"). Труба (трубопровод) .One (& соответственно) \t \t \t я мог читать только соотв [ "dept_list"], а не RESP [ "dept_list"] [ «crse_list»], потому что (тип interface {} не поддерживает индексирование). Я знаю, что есть способы превратить bson.M в массив, а затем проиндексировать его оттуда, но я искал везде и еще не нашел того, что работает. –

+1

Посмотрите документацию Go. Найдите утверждения типа. –

+0

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

0

После прочтения документов mongo я считаю, что предпочтительным способом осуществления вложенных отношений является использование древовидных структур с материализованными путями, как описано here на mongo.

Также имеются деревья array of ancestors и parent/child references. Взглянуть.

Кажется, использование деревьев проще, элегантнее и экономит много технических хлопот.

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

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