2015-11-25 6 views
0

У меня есть объект здания, в котором внутри находится массив объектов пола.MongoDB (Mgo v2) Projection возвращает родительскую структуру

При проектировании моя цель - вернуть или подсчитать количество объектов пола внутри объекта здания после соответствующего соответствия элементов. Код выглядит следующим образом:

объектов:

type Floor struct { 
    // Binary JSON Identity 
    ID bson.ObjectId `bson:"_id,omitempty"` 
    // App-level Identity 
    FloorUUID string `bson:"f"` 
    // Floor Info 
    FloorNumber int `bson:"l"` 
    // Units 
    FloorUnits []string `bson:"u"` 
    // Statistics 
    Created time.Time `bson:"y"` 
} 

type Building struct { 
    // Binary JSON Identity 
    ID bson.ObjectId `bson:"_id,omitempty"` 
    // App-level Identity 
    BldgUUID string `bson:"b"` 
    // Address Info 
    BldgNumber string `bson:"i"` // Street Number 
    BldgStreet string `bson:"s"` // Street 
    BldgCity string `bson:"c"` // City 
    BldgState string `bson:"t"` // State 
    BldgCountry string `bson:"x"` // Country 
    // Building Info 
    BldgName  string `bson:"w"` 
    BldgOwner  string `bson:"o"` 
    BldgMaxTenant int `bson:"m"` 
    BldgNumTenant int `bson:"n"` 
    // Floors 
    BldgFloors []Floor `bson:"p"` 
    // Statistics 
    Created time.Time `bson:"z"` 
} 

Код:

func InsertFloor(database *mgo.Database, bldg_uuid string, fnum int) error { 

    fmt.Println(bldg_uuid) 
    fmt.Println(fnum) // Floor Number 

    var result Floor // result := Floor{} 

    database.C("buildings").Find(bson.M{"b": bldg_uuid}).Select(
     bson.M{"p": bson.M{"$elemMatch": bson.M{"l": fnum}}}).One(&result) 

    fmt.Printf("AHA %s", result) 
    return errors.New("x") 
} 

Это не получается, независимо от того, как я пытаюсь запрос возвращает объект здания, а не объект этаж? Какие изменения мне нужно сделать, чтобы получить выборку и подсчет запросов, а не здания?

Это делается для того, чтобы проверить, существует ли Этаж внутри здания перед вставкой. Если есть лучший подход, я заменил бы меня тем лучше!

Спасибо!

+0

ли мой ответ решить эту проблему? Если да, пожалуйста, примите, что это правильный ответ. – Pio

+0

Я использовал конвейер, который был другим и быстрее, чем тот, который у вас был .. так не совсем, но достаточно близко. –

ответ

1

Вы запрашиваете документ Building, поэтому mongo возвращает это вам, даже если вы пытаетесь замаскировать некоторые его поля, используя проекцию.

Я не знаю способа подсчета количества элементов в массиве mongo в find запросе, но вы можете использовать структуру агрегации, где у вас есть $size оператор, который делает именно это. Таким образом, вы должны отправить запрос, как это mongo:

db.buildings.aggregate([ 
{ 
    "$match": 
    { 
     "_id": buildingID, 
     "p": { 
      "$elemMatch": {"l": fNum} 
     } 
    } 
}, 
{ 
    "$project": 
    { 
     nrOfFloors: { 
      "$size": "$p" 
     } 
    } 
}]) 

go Который в это будет выглядеть

result := []bson.M{} 
match := bson.M{"$match": bson.M{"b": bldg_uuid, "p": bson.M{"$elemMatch": bson.M{"l": fNum}}}} 
count := bson.M{"$project": bson.M{"nrOfFloors": bson.M{"$size": "$p"}}} 
operations := []bson.M{match, count} 
pipe := sess.DB("mgodb").C("building").Pipe(operations) 
pipe.All(&result) 
+0

Но я думал, что пол уже внутри массива внутри здания? Вы прочитали код? Уникальные идентификаторы для удобства использования. Это не имеет ничего общего с философией NoSQL монго. –