英文:
When using the mongodb $in query, the "(BadValue) $in needs an array" error occurs if [] uint8 is used for the query. Why?
问题
大家好。当我在mongodb的$in查询选择器中使用[]uint8数组时,会出现"(BadValue) $in needs an array"错误。有人可以给我一些帮助吗?谢谢!!!
以下是我复现的步骤:
Mongodb信息
mongodb驱动程序版本为v1.8.1
$ mongo --host 192.168.64.6
MongoDB shell version v4.0.3
connecting to: mongodb://192.168.64.6:27017/
Implicit session: session { "id" : UUID("e4d7cea2-ab81-45ad-a51e-e7acf45a7242") }
MongoDB server version: 4.4.8
WARNING: shell and server versions do not match
mongos> use testing
switched to db testing
mongos> db.numbers.find()
{ "_id" : ObjectId("61b71d3d73b251bceee62032"), "type" : 0, "value" : 0 }
{ "_id" : ObjectId("61b71d3d73b251bceee62033"), "type" : 1, "value" : 1 }
{ "_id" : ObjectId("61b71d3d73b251bceee62034"), "type" : 2, "value" : 2 }
{ "_id" : ObjectId("61b71d3d73b251bceee62035"), "type" : 3, "value" : 3 }
{ "_id" : ObjectId("61b71d3d73b251bceee62036"), "value" : 4, "type" : 4 }
{ "_id" : ObjectId("61b71d3d73b251bceee62037"), "value" : 5, "type" : 5 }
{ "_id" : ObjectId("61b71d3d73b251bceee62038"), "type" : 6, "value" : 6 }
{ "_id" : ObjectId("61b71d3d73b251bceee62039"), "type" : 7, "value" : 7 }
{ "_id" : ObjectId("61b71d3d73b251bceee6203a"), "type" : 8, "value" : 8 }
{ "_id" : ObjectId("61b71d3d73b251bceee6203b"), "type" : 9, "value" : 9 }
Go代码
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
)
func main() {
// 初始化mongodb客户端
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://192.168.64.6:27017/"))
if err != nil {
fmt.Println(err)
return
}
// 模拟一些数据
collection := client.Database("testing").Collection("numbers")
for i := 0; i < 10; i++ {
_, err = collection.InsertOne(ctx, bson.M{"type": uint8(i), "value": i})
if err != nil {
fmt.Println(err)
return
}
}
// 查询
filter := bson.M{"type": bson.M{"$in": []uint8{1, 2, 3}}}
res := collection.FindOne(ctx, filter)
if err = res.Err(); err != nil {
fmt.Println(err)
return
}
}
结果
当我在命令行上运行该命令时,我得到以下输出:
go run main.go
(BadValue) $in needs an array
英文:
everyone.When I use []uint8 array in mongodb $in query selector , "(BadValue) $in needs an array" error occurs.
Could someone give me some help? Thanks !!!
Here are my reproduction steps:
Mongodb Info
mongodb driver version is v1.8.1
$ mongo --host 192.168.64.6
MongoDB shell version v4.0.3
connecting to: mongodb://192.168.64.6:27017/
Implicit session: session { "id" : UUID("e4d7cea2-ab81-45ad-a51e-e7acf45a7242") }
MongoDB server version: 4.4.8
WARNING: shell and server versions do not match
mongos> use testing
switched to db testing
mongos> db.numbers.find()
{ "_id" : ObjectId("61b71d3d73b251bceee62032"), "type" : 0, "value" : 0 }
{ "_id" : ObjectId("61b71d3d73b251bceee62033"), "type" : 1, "value" : 1 }
{ "_id" : ObjectId("61b71d3d73b251bceee62034"), "type" : 2, "value" : 2 }
{ "_id" : ObjectId("61b71d3d73b251bceee62035"), "type" : 3, "value" : 3 }
{ "_id" : ObjectId("61b71d3d73b251bceee62036"), "value" : 4, "type" : 4 }
{ "_id" : ObjectId("61b71d3d73b251bceee62037"), "value" : 5, "type" : 5 }
{ "_id" : ObjectId("61b71d3d73b251bceee62038"), "type" : 6, "value" : 6 }
{ "_id" : ObjectId("61b71d3d73b251bceee62039"), "type" : 7, "value" : 7 }
{ "_id" : ObjectId("61b71d3d73b251bceee6203a"), "type" : 8, "value" : 8 }
{ "_id" : ObjectId("61b71d3d73b251bceee6203b"), "type" : 9, "value" : 9 }
Go Code
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
)
func main() {
// init mongodb client
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://192.168.64.6:27017/"))
if err != nil {
fmt.Println(err)
return
}
// mock some data
collection := client.Database("testing").Collection("numbers")
for i := 0; i < 10; i++ {
_, err = collection.InsertOne(ctx, bson.M{"type": uint8(i), "value": i})
if err != nil {
fmt.Println(err)
return
}
}
// query
filter := bson.M{"type": bson.M{"$in": []uint8{1, 2, 3}}}
res := collection.FindOne(ctx, filter)
if err = res.Err(); err != nil {
fmt.Println(err)
return
}
}
Result
When I start the command on the command line, I get the following output:
go run main.go
(BadValue) $in needs an array
答案1
得分: 1
uint8
是byte
的别名,而[]byte
是一种特殊类型,它与其他切片类型处理方式不同(不是作为数字切片处理)。[]byte
的值使用bsoncodec.ByteSliceCodec
进行编码,而其他切片值使用bsoncodec.SliceCodec
进行编码。
可以使用任何其他数字类型的切片,例如[]int8
或[]int
:
filter := bson.M{"type": bson.M{"$in": []int{1, 2, 3}}}
注意:Mongo驱动程序有自己的BSON实现和包,请使用go.mongodb.org/mongo-driver/bson
。在你的示例中,你导入并使用的是gopkg.in/mgo.v2/bson
,这是一个完全不同的BSON实现,作为mgo
驱动程序的一部分开发(现已不再支持和过时)。不要混用不同的驱动程序。
英文:
uint8
is an alias to byte
, and []byte
is a special type, it's handled differently than other slice types (not as a slice of numbers). []byte
values are encoded using bsoncodec.ByteSliceCodec
and other slice values are encoded using bsoncodec.SliceCodec
.
Use a slice of any other number type, e.g. []int8
or []int
:
filter := bson.M{"type": bson.M{"$in": []int{1, 2, 3}}}
Note: the mongo driver has its own BSON implementation and package, do use that: go.mongodb.org/mongo-driver/bson
. In your example you are importing and using gopkg.in/mgo.v2/bson
which is a completely different BSON implementation, developed as part of the mgo
driver (now unsupported and obsolete). Do not mix different drivers.
答案2
得分: 0
你应该移除将i
转换为uint8
的操作,并使用以下正确的代码来获取数据。
// 模拟一些数据
collection := client.Database("testing").Collection("numbers")
for i := 0; i < 10; i++ {
_, err = collection.InsertOne(ctx, bson.M{"type": i, "value": i})
if err != nil {
fmt.Println(err)
return
}
}
res := collection.FindOne(ctx, bson.M{
"type": bson.M{
"$in": []int{1, 2, 3},
},
})
if res.Err() != nil {
// 处理错误
}
// 然后你可以将数据作为原始字节获取,或解码为其他类型,例如:
res.DecodeBytes()
英文:
You should remove conversion of i
to uint8
, and for getting data correct code like this.
// mock some data
collection := client.Database("testing").Collection("numbers")
for i := 0; i < 10; i++ {
_, err = collection.InsertOne(ctx, bson.M{"type": i, "value": i})
if err != nil {
fmt.Println(err)
return
}
}
res := collection.FindOne(ctx, bson.M{
"type": bson.M{
"$in": []int{1, 2, 3},
},
})
if res.Err()!=nil{
// handle error
}
Then you can get data as raw or decode into another type, like:
res.DecodeBytes()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论