When using the mongodb $in query, the "(BadValue) $in needs an array" error occurs if [] uint8 is used for the query. Why?

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

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 { &quot;id&quot; : UUID(&quot;e4d7cea2-ab81-45ad-a51e-e7acf45a7242&quot;) }
MongoDB server version: 4.4.8
WARNING: shell and server versions do not match

mongos&gt; use testing
switched to db testing
mongos&gt; db.numbers.find()
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62032&quot;), &quot;type&quot; : 0, &quot;value&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62033&quot;), &quot;type&quot; : 1, &quot;value&quot; : 1 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62034&quot;), &quot;type&quot; : 2, &quot;value&quot; : 2 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62035&quot;), &quot;type&quot; : 3, &quot;value&quot; : 3 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62036&quot;), &quot;value&quot; : 4, &quot;type&quot; : 4 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62037&quot;), &quot;value&quot; : 5, &quot;type&quot; : 5 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62038&quot;), &quot;type&quot; : 6, &quot;value&quot; : 6 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee62039&quot;), &quot;type&quot; : 7, &quot;value&quot; : 7 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee6203a&quot;), &quot;type&quot; : 8, &quot;value&quot; : 8 }
{ &quot;_id&quot; : ObjectId(&quot;61b71d3d73b251bceee6203b&quot;), &quot;type&quot; : 9, &quot;value&quot; : 9 }


Go Code

package main

import (
	&quot;context&quot;
	&quot;fmt&quot;
	&quot;time&quot;

	&quot;go.mongodb.org/mongo-driver/mongo&quot;
	&quot;go.mongodb.org/mongo-driver/mongo/options&quot;
	&quot;go.mongodb.org/mongo-driver/bson&quot;
)

func main() {
	// init mongodb client
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(&quot;mongodb://192.168.64.6:27017/&quot;))
	if err != nil {
		fmt.Println(err)
		return
	}

	// mock some data
	collection := client.Database(&quot;testing&quot;).Collection(&quot;numbers&quot;)
	for i := 0; i &lt; 10; i++ {
		_, err = collection.InsertOne(ctx, bson.M{&quot;type&quot;: uint8(i), &quot;value&quot;: i})
		if err != nil {
			fmt.Println(err)
			return
		}
	}

	// query
	filter := bson.M{&quot;type&quot;: bson.M{&quot;$in&quot;: []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

uint8byte的别名,而[]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{&quot;type&quot;: bson.M{&quot;$in&quot;: []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(&quot;testing&quot;).Collection(&quot;numbers&quot;)
for i := 0; i &lt; 10; i++ {
	_, err = collection.InsertOne(ctx, bson.M{&quot;type&quot;: i, &quot;value&quot;: i})
	if err != nil {
		fmt.Println(err)
		return
	}
}

 res := collection.FindOne(ctx, bson.M{
	&quot;type&quot;: bson.M{
		&quot;$in&quot;: []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()

huangapple
  • 本文由 发表于 2021年12月13日 19:51:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/70334198.html
匿名

发表评论

匿名网友

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

确定