gpt4 book ai didi

javascript - 如何通过其中包含 javascript 的 mongo_go_driver 运行聚合查询?

转载 作者:IT王子 更新时间:2023-10-29 01:51:56 28 4
gpt4 key购买 nike

我正在使用 mongo-go-driver ( https://godoc.org/github.com/mongodb/mongo-go-driver/mongo ) 并且我正在尝试做相当于

db.getCollection('mycollection').aggregate([
{ $lookup: {
from: "anothercollection",
localField: "_id",
foreignField: "foreignID",
as: "matched_docs"
}},
{ $match: { "matched_docs": { $eq: [] } } },
{ $project: { "matched_docs": 0 } },
{ $match: {"dateTimeGMT":{$lt: (new Date(Date.now()-1000*60*60*24)).toISOString()}} }
])

我不知道如何在使用此方法时放入 Javascript 命令。

pipeline := bson.NewArray(
bson.VC.DocumentFromElements(
bson.EC.SubDocumentFromElements(
//yada, yada, yada...
cursor, err := collection.Aggregate(ctx, pipeline)

(总的来说,我不喜欢这种方法。我希望能够在 Robo 3T 中设计查询并将它们复制到我的代码中,就像我在 MySQL Workbench 和 PHP 中所做的那样)

此方法在管道中产生一个空的 *bson.Array

pipelineJSON := `[
{ $lookup: {
from: "anothercollection",
localField: "_id",
foreignField: "interactionID",
as: "matched_docs"
}},
{ $match: { "matched_docs": { $eq: [] } } },
{ $project: { "matched_docs": 0 } },
{ $match: {"dateTimeGMT":{$lt: (new Date(Date.now()-1000*60*60*24)).toISOString()}} }
]`
pipeline, err = bson.ParseExtJSONArray(pipelineJSON)

如果有一种方法可以将命令作为字符串发送给 Mongo(就像我将其输入到 Robo 3T 中一样)并返回一个 *mongo.Cursor,我会非常喜欢它。我应该改用更好的驱动程序(仍然有人支持)吗?我需要自己编写代码吗?

谢谢!

最佳答案

I can't figure out how to put the Javascript commands in using this method.

虽然我知道这不是您用例的首选方法,但这是构建 aggregation pipeline 的方法作为bson.D使用 mongo-go-driver v1.0:

pipeline := mongo.Pipeline{
{{"$lookup", bson.D{
{"from", "tour"},
{"localField", "_id"},
{"foreignField", "foreignID"},
{"as", "matched_docs"},
}}},
{{"$match", bson.D{
{"matched_docs", bson.D{
{"$eq", bson.A{}}},
},
}}},
{{"$project", bson.D{
{"matched_docs", 0},
}}},
{{"$match", bson.D{
{"dateTimeGMT", bson.D{
{"$lt", time.Now().AddDate(0, 0, -1).UTC().Format(time.RFC3339)},
},
},
}}},
}

{ $project: { "matched_docs": 0 } },

您也可以将两个 $match 组合成一个管道阶段,然后在末尾附加 $project。例如:

db.collection.aggregate([
{ "$lookup":{
"from":"anothercollection",
"localField":"_id",
"foreignField":"foreignID",
"as":"matched_docs"}
},
{ "$match": { "matched_docs": { "$eq": [] },
"datetimegmt": { "$lt": (new Date(Date.now()-1000*60*60*24)).toISOString() }
}
},
{ "$project": { "matched_docs": 0 } }
]);

{ $match: {"dateTimeGMT":{$lt: (new Date(Date.now()-1000*60*60*24)).toISOString()}} }

根据 $match 值,您似乎将日期存储为 string 而不是 Date目的。我建议将日期存储为适当的 Date 对象以获得更好的索引性能。

Using ParseExtJSONArray DOES work, but, unlike Mongo Shell, you cannot include JS or unquoted aggregation stages / expression operators

mongo shell 提供了一些方便的方法/类型,即 ObjectID() 等来构造 MongoDB Extended JSON . mongo shell 不仅仅是一个 JavaScript shell。

如果您的目标只是评估 JavaScript 表达式,您可以使用 Go 的 JavaScript 解释器 (otto)。一个粗略的例子是:

// Note the unquoted fields, as JSON is JavaScript native. 
raw := `[
{ "$lookup": {
from: "anothercollection",
localField: "_id",
foreignField: "foreignID",
as: "matched_docs"
}},
{ $match: { "matched_docs": { $eq: [] },
"dateTimeGMT":{$lt: (new Date(Date.now()-1000*60*60*24)).toISOString() },
}
},
{ $project: { "matched_docs": 0 } },
]`
vm := otto.New()
// Evaluate JS expression
jsvalue, err := vm.Eval(raw)

// Export to Go interface{}
output, err := jsvalue.Export()

// Convert interface{} to bson.Document bytes
bsonbytes, err := bson.Marshal(output)

// Convert bson.Document bytes to bson.Document
pipeline, err := bson.UnmarshalDocument(bsonbytes)

请注意,如上所述,有一些对象无法被普通的 JavaScript 解释器识别,即 ObjectId()

I want to be able to design queries in Robo 3T and copy them to my code just like I do with MySQL Workbench and PHP

虽然目前不支持Go,值得一提的是MongoDB Compass具有 Export Query to Language 的功能.当前版本 (1.15) 支持 Java、Node、C# 和 Python3。希望 Go 会在未来。

关于javascript - 如何通过其中包含 javascript 的 mongo_go_driver 运行聚合查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52235070/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com