【问题标题】:MongoDB (Mgo v2) Projection returns parent structMongoDB(Mgo v2)投影返回父结构
【发布时间】:2016-02-28 09:52:54
【问题描述】:

我这里有一个建筑对象,里面有一个地板对象数组。

在投影时,我的目标是在相应地匹配元素后返回或计算建筑物对象内的楼层对象的数量。代码如下:

对象:

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")
}

事实证明,无论我如何尝试查询返回的是建筑对象,而不是楼层对象?为了让查询获取和计算楼层而不是建筑物,我需要进行哪些更改?

这样做是为了在插入之前检查建筑物内的楼层是否已经存在。如果有更好的方法,我会用更好的方法代替!

谢谢!

【问题讨论】:

  • 我的回答解决了问题吗?如果是这样,请接受是一个正确的答案。
  • 我使用的管道与您使用的管道不同且速度更快。所以不太接近但足够接近。

标签: mongodb go projection mgo database


【解决方案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)

【讨论】:

  • 但我认为地板已经在建筑物内的阵列中?你读过代码吗??唯一的 ID 可以让事情变得方便。它与 mongo 的 NoSQL 哲学无关。
猜你喜欢
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多