问题是使用golang bson从mongo获取整个元素,而仅返回了子元素

时间:2018-08-07 15:07:12

标签: mongodb go bson mgo

我正在使用mgo在golang中使用mongo查询来查询子元素以返回整个元素

{
    "_id" : ObjectId("5b64a0d3931653c36bcaf0b5"),
    "quantity" : 2,
    "product" : "ABC",   
    "children" : [ 
        {           
            "isBlocked" : true,
            "blockedMessage" : "Error occurred: TRACEID",
            "serialNo" : "abc123",
            "token" : "foo456",            
        }
    ]
}

我在下面使用的查询    bson.M {“ _ id”:0,“ children”:bson.M {“ $ elemMatch”:{serialNo:'abc123'}}}

Find(MongoSpec{Selector: bson.M{}, Query: bson.M{"_id": 0, "children": bson.M{"$elemMatch": fields}}})

下面是查找功能

    documents := []interface{}{}
        s := spec.(MongoSpec).Selector
        q := spec.(MongoSpec).Query
        query := session.
            DB(repo.Config.DatabaseName).
            C(repo.CollectionName).
            Find(s)

        if q != nil {
            query = query.Select(q)
        }

        err := query.All(&documents)

MongoSpec结构

  type MongoSpec struct {
        Selector interface{}
        Query    interface{}
    }

上面的查询工作正常,但仅返回以下子元素

"children" : [ 
            {           
                "isBlocked" : true,
                "blockedMessage" : "Error occurred: TRACEID",
                "serialNo" : "abc123",
                "token" : "foo456",            
            }
        ]

我没有得到查询的问题。

1 个答案:

答案 0 :(得分:1)

$elemMatch query projection的形式存在。查询实际上是用来过滤文件被返回,并且投影确定所显示的文件的哪一部分。重申一下:Projection不会过滤返回的文档,它会限制每个文档返回的值(类似于SQL的SELECT部分)。

mgo的Find函数是查询,而Select是投影。因此,您希望最终代码看起来更接近此:

c.Find(
    bson.M{
        "children": bson.M{
            "$elemMatch": bson.M{serialNo: "abc123"},
        },
    },
).Select(
    bson.M{
        "_id": 0,
    },
)

代码的设置方式如下所示。

Find(
    MongoSpec{
        Selector: bson.M{"children": bson.M{"$elemMatch": fields}},
        Query: bson.M{"_id": 0},
    },
)

但是,我强烈建议您重命名MongoSpec中的字段(完全删除它和Find函数可能也不是一个坏主意)。您将Query用作投影(.Select()函数),并将Selector用作查询(.Find())。这也许就是您首先犯此错误的原因。