Mongo过滤器在Mongo shell中有效,但在Go中编写时无效。

huangapple go评论83阅读模式
英文:

Mongo filter works inside the mongo shell but doesn't work when written in go

问题

以下是翻译的内容:

Mongo: 4.4
Go: 1.17.3

我正在尝试获取字符串字段值长度大于四个字符的文档。
这是我在mongo的shell中使用的查询语句:

db.player.find({
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 4 ] } 
})

这是相同的查询语句,但在go中以bson过滤器的形式编码:

longName := bson.M{
    "name": bson.M{"$exists": true},
    "$expr": bson.M{
        "$gt": bson.A{
            bson.M{"$strLenCP": "$name"},
            4,
        },
    },
}
fmc, err := collection.Find(context.TODO(), longName)
if err != nil {
    log.Panic(err)
}
var longBoi models.Player
err = fmc.Decode(&longBoi)
if err != nil {
    log.Panic(err) 
    // 在这里发生panic: 
    // 2021/12/15 15:53:46 EOF
    // panic: EOF
}

第一个查询将输出字符串字段值长度大于指定数字的文档。第二个查询将出现EOF、时间戳和调用堆栈的错误。调试器显示fmc游标中的batch不包含任何数据。

第二种情况出了什么问题?

英文:

Mongo: 4.4
Go: 1.17.3

I'm trying to get documents with string field value longer than four symbols.
Here is the query I use inside mongo's shell:

db.player.find({
    "name": { "$exists": true },
        "$expr": { "$gt": [ { "$strLenCP": "$name" }, 4 ] } 
    })

And here is the same query but coded as bson filter in go:

longName := bson.M{
    "name": bson.M{"$exists": true},
	"$expr": bson.M{
		"$gt": bson.A{
			bson.M{"$strLenCP": "$name"},
			4,
		},
	},
}
fmc, err := collection.Find(context.TODO(), longName)
if err != nil {
	log.Panic(err)
}
var longBoi models.Player
err = fmc.Decode(&longBoi)
if err != nil {
	log.Panic(err) 
    // panic here: 
    // 2021/12/15 15:53:46 EOF
    // panic: EOF
}

The first will output desired documents with string field value length longer than certain number. The second will error with just EOF, timestamp and callstack. Debugger says that batch inside coursor fmc contains no data.

What's wrong in the second case?

答案1

得分: 1

以下是修复问题的代码:

var longBoi []models.Player
err = fmc.All(context.TODO(), &longBoi)
if err != nil {
	log.Panic(err)
}

Find() 返回的是 Cursor(),而不是文档。然后可以使用游标来迭代匹配过滤器的文档,通过调用 All() 或其他方法。

英文:

The following fixes the problem:

var longBoi []models.Player
err = fmc.All(context.TODO(), &longBoi)
if err != nil {
	log.Panic(err)
}

Find() returns the Cursor(), not the documents. The cursor then can be used to iterate over documents matching the filter by calling All() or some other method.

huangapple
  • 本文由 发表于 2021年12月15日 20:20:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/70363597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定