简体   繁体   English

InvalidPipelineOperator 用于在 mongodb 中使用 golang 进行聚合和过滤

[英]InvalidPipelineOperator for aggregation and filtering in mongodb with golang

I have a mongodb collection with the following structure:我有一个具有以下结构的 mongodb 集合:

{
        "_id" : ObjectId("5e2af47006d5b7820876cc34"),
        "uuid" : "6ec5245e-d512-4496-995d-9a7d1073ff80",
        "beaconid" : "fc775907-f442-43ca-9b86-78fede5f9218",
        "locations" : [
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T13:43:12.895Z")
                },
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T13:47:09.066Z")
                },
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T15:03:02.770Z")
                },
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T15:23:36.891Z")
                }
}
{
     ......
}

I am currently developing an API to get the all the locations with in a particular time range using mongodb's aggregation and filtering functions in golang.我目前正在开发一个 API,以使用 golang 中的 mongodb 聚合和过滤功能获取特定时间范围内的所有位置。

For example: I would like to retrieve all values from ISODate("2020-01-24T13:45:00.066Z") to ISODate("2020-01-24T15:10:00.770Z"), which only retrieve the middle two locations, the output should be following:例如:我想检索从 ISODate("2020-01-24T13:45:00.066Z") 到 ISODate("2020-01-24T15:10:00.770Z") 的所有值,它只检索中间两个位置,输出应如下:

{
        "_id" : ObjectId("5e2af47006d5b7820876cc34"),
        "uuid" : "6ec5245e-d512-4496-995d-9a7d1073ff80",
        "beaconid" : "fc775907-f442-43ca-9b86-78fede5f9218",
        "locations" : [
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T13:47:09.066Z")
                },
                {
                        "longitude" : 464.4,
                        "latitude" : 34.8,
                        "establish" : ISODate("2020-01-24T15:03:02.770Z")
                }
}

To achieve this, I have referenced the following two webpages for making the pipeline for the aggregation and filtering:为了实现这一点,我参考了以下两个网页来制作聚合和过滤的管道:

https://github.com/simagix/mongo-go-examples/blob/5a04bab8b677e7b160dbe4c327f7ac68efb83ba5/examples/aggregate_reduce_test.go https://github.com/simagix/mongo-go-examples/blob/5a04bab8b677e7b160dbe4c327f7ac68efb83ba5/examples/aggregate_reduce_test.go

How to write bson form of mongo query in golang? 如何在golang中编写mongo查询的bson形式?

At first I have trouble using the github's mdb.MongoPipeline(pipeline), so I decide to use the github's pipeline format and use it in the form of second answer of stack overflow of mongo.Pipeline{...}起初我在使用github的mdb.MongoPipeline(pipeline)时遇到了麻烦,所以我决定使用github的pipeline格式,并以mongo.Pipeline{...}堆栈溢出的第二个答案的形式使用它

The resulting pipeline becomes:生成的管道变为:

new_pipeline = mongo.Pipeline{
    {{"$match", bson.D{
         {"beaconID", r.URL.Query()["beaconid"][0]},
    }}},
    {{"$project", bson.D{
         {"locations", bson.D{
              {"$filter", bson.D{
                  {"input", "$locations"},
                  {"as", "locations"},
                  {"cond", bson.D{
                       {"$and", bson.D{
                           {"$lte", bson.D{{"locations.establish", r.URL.Query()["rangeend"][0]}}},
                           {"$gtd", bson.D{{"locations.establish", r.URL.Query()["rangebegin"][0]}}},
                       }},
                  }},
              }},
          }},
     }}},
     {{"$unwind", "$locations"}},
}

opts := options.Aggregate()
cursor, err := collection.Aggregate(context.TODO(), new_pipeline, opts)

However, by running the program there is an error which I don't know how to solve:但是,通过运行该程序,出现了一个我不知道如何解决的错误:

(Location15983) An object representing an expression must have exactly one field: { $lte: { $$locations.establish: new Date(1580122004573) }, $gtd: { $$locations.establish: new Date(1578826004573) } } (Location15983) 表示表达式的对象必须只有一个字段:{ $lte: { $$locations.establish: new Date(15801222004573) }, $gtd: { $$locations.establish: new Date(1578826004573) } }

And then when trying to debug by testing different pipeline cases, this pipeline causes another problem:然后当尝试通过测试不同的管道情况进行调试时,此管道会导致另一个问题:

...
{"as", "locations"},
      {"cond", bson.D{
            {"$lte", bson.D{{"$$locations.establish", r.URL.Query()["rangeend"][0]}}},
      }},
}},
...

Error is: (InvalidPipelineOperator) Unrecognized expression '$$locations.establish'错误是:(InvalidPipelineOperator) 无法识别的表达式 '$$locations.establish'

Any ideas why these two error happen?任何想法为什么会发生这两个错误? And how to fix it?以及如何修复它? Thank You.谢谢你。

Any ideas why these two error happen?任何想法为什么会发生这两个错误?

You're getting those errors because of the missing array operator.由于缺少数组运算符,您会收到这些错误。 The operator $and requires an array, which should be represented as bson.A .运算符$and需要一个数组,该数组应表示为bson.A

And how to fix it?以及如何修复它?

Please see the following pipeline:请参阅以下管道:

// Create a date object using time.Parse()
lteDate, err := time.Parse(time.RFC3339, "2020-01-24T15:10:00.770Z")
if err!=nil {log.Fatal(err)}
gteDate, err := time.Parse(time.RFC3339, "2020-01-24T13:45:00.066Z")
if err!=nil {log.Fatal(err)}

// MongoDB Aggregation Pipeline Stages
matchStage := bson.D{
    {"$match", bson.D{
        {"beaconid", "fc775907-f442-43ca-9b86-78fede5f9218"},
    }},
}

projectStage := bson.D{
    {"$project", bson.D{
        {"locations", bson.D{
            {"$filter", bson.D{
                {"input", "$locations"}, 
                {"as", "locations"}, 
                {"cond", bson.D{
                    {"$and", bson.A{
                            bson.D{{"$lte", bson.A{"$$locations.establish", lteDate}}},
                            bson.D{{"$gte", bson.A{"$$locations.establish", gteDate}}},
                    }},
                }}, 
            }}, 
        }}, 
    }}, 
}

unwindStage := bson.D{
    {"$unwind", "$locations"},
}
pipeline := mongo.Pipeline{matchStage, projectStage, unwindStage}

The snippet above is written using the current version of mongo-go-driver (v1.2.x)上面的代码片段是使用当前版本的mongo-go-driver (v1.2.x) 编写的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM