【问题标题】: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 需要数组”错误。为什么?
【发布时间】:2022-01-16 21:33:38
【问题描述】:

everyone.当我在 mongodb $in 查询选择器中使用 []uint8 数组时,出现“(BadValue) $in 需要一个数组”错误。 有人可以给我一些帮助吗?谢谢!!!

这是我的复制步骤:

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 }


转码

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
    }
}

结果

当我在命令行启动命令时,我得到以下输出:

go run main.go

(BadValue) $in needs an array

【问题讨论】:

  • mongodb驱动版本为v1.8.1

标签: mongodb go driver


【解决方案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 驱动程序的一部分开发(现在不受支持且已过时)。不要混用不同的驱动程序。

【讨论】:

  • 谢谢!使用“go.mongodb.org/mongo-driver/bson”也会出现“(BadValue)$in需要一个数组​”。我会使用 uint32。
  • @sinksmell 是的,同样的错误。为了简单和一致,我建议使用您正在使用的 mongo 驱动程序中的 BSON 实现,而不是避免该错误。错误的解决方法是使用另一种切片类型,而不是[]uint8,这就是答案。
【解决方案2】:

您应该删除 iuint8 的转换,以及像这样获取数据正确的代码。

// 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
}

然后您可以获取原始数据或解码为另一种类型,例如:

 res.DecodeBytes()

【讨论】:

  • 谢谢!在我的收藏中,有些数据以 uin8 格式存储。我想使用 $in 和 []uint8。确实用其他类型替换uint8可以解决问题,我们也使用过这种方法解决问题,但根本原因尚不清楚。
猜你喜欢
  • 2021-12-06
  • 2018-08-18
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
相关资源
最近更新 更多