英文:
MongoDB (Mgo v2) Projection returns parent struct
问题
我这里有一个Building对象,里面有一个Floor对象的数组。
在进行投影时,我的目标是根据匹配的元素返回或计算Building对象中Floor对象的数量。代码如下:
对象:
type Floor struct {
// 二进制JSON标识
ID bson.ObjectId `bson:"_id,omitempty"`
// 应用级标识
FloorUUID string `bson:"f"`
// 楼层信息
FloorNumber int `bson:"l"`
// 单元
FloorUnits []string `bson:"u"`
// 统计信息
Created time.Time `bson:"y"`
}
type Building struct {
// 二进制JSON标识
ID bson.ObjectId `bson:"_id,omitempty"`
// 应用级标识
BldgUUID string `bson:"b"`
// 地址信息
BldgNumber string `bson:"i"` // 街道号码
BldgStreet string `bson:"s"` // 街道
BldgCity string `bson:"c"` // 城市
BldgState string `bson:"t"` // 州/省
BldgCountry string `bson:"x"` // 国家
// 建筑信息
BldgName string `bson:"w"`
BldgOwner string `bson:"o"`
BldgMaxTenant int `bson:"m"`
BldgNumTenant int `bson:"n"`
// 楼层
BldgFloors []Floor `bson:"p"`
// 统计信息
Created time.Time `bson:"z"`
}
代码:
func InsertFloor(database *mgo.Database, bldg_uuid string, fnum int) error {
fmt.Println(bldg_uuid)
fmt.Println(fnum) // 楼层号码
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")
}
结果发现,无论我如何尝试,查询都返回一个Building对象,而不是一个Floor对象。为了使查询获取和计算楼层而不是建筑物,我需要做出哪些改变?
这样做是为了在插入之前检查Building内是否已经存在一个Floor。如果有更好的方法,我会用更好的方法替换我的方法!
谢谢!
英文:
I have here a Building Object where inside sits an Array of Floor Objects.
When Projecting, my goal is to return or count the number of Floor Objects inside a Building Object after matching the elements accordingly. The code is as follows:
Objects:
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"`
}
Code:
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")
}
It turns out, no matter how I try the query returns a Building Object, not a floor object? What changes do I need to make in order to have the query fetch and count Floors and not Buildings?
This is done so to check if a Floor inside Building already exists before insertion. If there's a better a approach then I'll replace mine with the better!
Thanks!
答案1
得分: 1
您正在查询一个名为Building
的文档,所以mongo
会返回该文档,即使您尝试使用投影来隐藏其中的一些字段。
我不知道如何在find
查询中计算mongo
数组中的元素数量,但您可以使用聚合框架,在其中使用$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)
以上是翻译好的内容,请查看。
英文:
You are querying for a Building
document so mongo
returns that to you even though you try to mask some of its fields using projection.
I don't know of a way to count the number of elements in a mongo
array in a find
query, but you can use the aggregation framework, where you have the $size
operator that does exactly this. So you should send a query like this to mongo
:
db.buildings.aggregate([
{
"$match":
{
"_id": buildingID,
"p": {
"$elemMatch": {"l": fNum}
}
}
},
{
"$project":
{
nrOfFloors: {
"$size": "$p"
}
}
}])
Which in go
it would look like
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论