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

I am working on a mongo query in golang using mgo to query a child element to return the entire element

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

The query I am using in below 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}}})

Below is the find function

    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 struct

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

The above query works fine but returns only children element as below

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

I am not getting what is wrong with the query.

dongwh1992
dongwh1992 添加了更多代码
大约 2 年之前 回复
doujiazong0322
doujiazong0322 添加了更多go代码,因为我在mongoCLI上查询没有任何问题
大约 2 年之前 回复
dsfsda121545
dsfsda121545 您发布的Go代码片段并不能证明您得到的结果是合理的。如果您需要帮助,则需要发布更多代码,以尽量减少可重复的示例为目标。到目前为止,这个问题已不在主题之列。
大约 2 年之前 回复
dongxilan9351
dongxilan9351 请添加更多您的Go代码。我想我知道这个问题,但想在回答之前通过查看Go代码进行验证。
大约 2 年之前 回复
doudi1979
doudi1979 您是否直接在mongoCLI(或其他mongo工具)中尝试了查询?如果得到相同的结果,那么这纯粹是一个mongodb问题,而不是Go问题。如果这实际上是Go问题,我们将需要查看相关的Go代码。
大约 2 年之前 回复

1个回答



$ elemMatch </ code>既作为 查询 </ strong>和 投影。</ strong>。查询用于实际过滤返回的文档</ strong>,然后由投影确定 显示返回的那部分文档</ strong>。 重申一下:Projection不会筛选返回的文档,它会限制每个文档返回的值(类似于SQL的 SELECT </ code>部分)。</ p>

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

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


</ code> </ pre>

代码的设置方式如下所示。</ p>

 查找(\  n MongoSpec {
选择器:bson.M {“儿童”:bson.M {“ $ elemMatch”:字段}},
查询:bson.M {“ _ id”:0},
},


</ code> </ pre>

但是,我强烈建议您重命名 MongoSpec </ code>中的字段(完全删除它和Find函数可能并不坏 想法)。 您使用 Query </ code>作为投影( .Select()</ code>函数),并使用 Selector </ code>作为查询( .Find() </代码>)。 这也许就是您首先犯此错误的原因。</ p>
</ div>

展开原文

原文

$elemMatch exists as both a query and a projection. A query is used to actually filter which documents are returned, and a projection determines which part of the documents returned are shown. To reiterate: Projection doesn't filter which documents are returned, it limits which values per document are returned (similar to the SELECT part of SQL).

mgo's Find function is the query, and Select is the projection. Therefore, you want your final code to look closer to this:

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

With how you have your code set up, this is how it would look.

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

However, I'd strongly advise you rename the fields in MongoSpec (dropping it and the Find function altogether might not be a bad idea, too). You use Query as your projection (the .Select() function) and you use Selector as your query (.Find()). That may be why you made this mistake in the first place.

dqpd4268
dqpd4268 您能否将投影词组修改为“投影”不过滤返回的文档,它限制了每个文档返回的值。 投影不仅发生在服务器中,而且发生在服务器中,投影可以帮助减少网络带宽并实现覆盖的查询状态。 谢谢
大约 2 年之前 回复
dtcn30461
dtcn30461 当然。 我之前的评论是对最后一段的回应
大约 2 年之前 回复
douduoting8408
douduoting8408 没问题! :)请参阅我刚刚添加的最后一段...我认为您可能不小心交换了MongoSpec中的Selector和Query字段的名称...进行了修复,使您的代码更易于阅读。
大约 2 年之前 回复
dougao1542
dougao1542 真棒! 谢谢,是的,你是对的。 我将按照建议进行更改。 谢谢!
大约 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐