Mongo 3.6 的聚合问题
Aggregation issue with Mongo 3.6
我在连接 3.4 mongodb 时使用聚合函数没有任何问题。
当我改为 3.6 分贝时,
我收到消息:'cursor' 选项是必需的,但带有解释参数的聚合除外。
抱歉,如果它已经发布了。我找不到任何解决方案
在mongo 3.6 中,使用聚合时必须使用游标,除非包含解释选项,否则必须指定游标选项。我遇到了和你一样的错误。现在你必须像
那样做
this.aggregate( [
{ $unwind : "$tags" },
{$group: {_id: '$tags', count: { $sum: 1} }},
{$sort: { count: 1 }}
] ).cursor({}).exec();
现在您可以使用游标方法 cursor.toArray() 来 return 一个包含游标中所有文档的数组。从聚合中 return 编辑的游标仅支持对已评估游标进行操作的游标方法,例如 cursor.toArray(),要了解更多游标方法,您可以单击 here 并进一步了解。
在 Node.js 中,将 MongoDB 从 3.4 升级到 3.6 后,有两件事需要检查:
在聚合语句中添加cursor: {}
选项。在以前的 MongoDB 版本中,这是可选的(当然,如果需要,您可以在游标对象中定义 batchSize)。例如:
db.collection(collectionName).aggregate(pipelineArray, {
cursor: {}
}, function(error, result) {
...
});
如果上述代码挂起且未调用回调,请检查mongodb
驱动程序版本。我在 mongodb
模块 v2.2.16 中遇到了这个 "not responding" 问题。 mongodb
升级到v2.2.35后修复
对于那些在 3.6 上尝试找出完整示例有问题的人,这对我有用:
function aggregateLoad(db, collectionName, lookUpOption, matchOption, callback) {
var defCursor = {};
var cursor = db.collection(collectionName).aggregate([
{
$lookup: lookUpOption
},
{
$match: matchOption
}
],defCursor,null);
cursor.toArray(function(err, docs) {
console.log("Some data: ", docs);
callback(err, docs);
db.close();
});
}
那么你可以调用上面的函数:
function testAggregateLoad(someId, callback) {
var match = {
"localId": someId
};
var aggregateQuery = {
from: "someSecondCollectionName",
localField: "localId",
foreignField: "_id",
as: "someData"
};
getConnection(conCallBackEx);
function conCallBackEx(db) {
aggregateLoad(db, "someBaseLoadCollection", aggregateQuery, match, onSuccess);
}
function onSuccess(err, json) {
console.log('Loaded data is ', json);
callback(json);
}
}
function getConnection(callback) {
var MongoClient = require('mongodb').MongoClient;
return MongoClient.connect(url, function (err, db) {
if (null === err) {
callback(db, err);
} else {
console.log("failed to get db connection retrying " + err);
getConnection(callback);
}
});
}
我在连接 3.4 mongodb 时使用聚合函数没有任何问题。
当我改为 3.6 分贝时,
我收到消息:'cursor' 选项是必需的,但带有解释参数的聚合除外。
抱歉,如果它已经发布了。我找不到任何解决方案
在mongo 3.6 中,使用聚合时必须使用游标,除非包含解释选项,否则必须指定游标选项。我遇到了和你一样的错误。现在你必须像
那样做this.aggregate( [
{ $unwind : "$tags" },
{$group: {_id: '$tags', count: { $sum: 1} }},
{$sort: { count: 1 }}
] ).cursor({}).exec();
现在您可以使用游标方法 cursor.toArray() 来 return 一个包含游标中所有文档的数组。从聚合中 return 编辑的游标仅支持对已评估游标进行操作的游标方法,例如 cursor.toArray(),要了解更多游标方法,您可以单击 here 并进一步了解。
在 Node.js 中,将 MongoDB 从 3.4 升级到 3.6 后,有两件事需要检查:
在聚合语句中添加
cursor: {}
选项。在以前的 MongoDB 版本中,这是可选的(当然,如果需要,您可以在游标对象中定义 batchSize)。例如:db.collection(collectionName).aggregate(pipelineArray, { cursor: {} }, function(error, result) { ... });
如果上述代码挂起且未调用回调,请检查
mongodb
驱动程序版本。我在mongodb
模块 v2.2.16 中遇到了这个 "not responding" 问题。mongodb
升级到v2.2.35后修复
对于那些在 3.6 上尝试找出完整示例有问题的人,这对我有用:
function aggregateLoad(db, collectionName, lookUpOption, matchOption, callback) {
var defCursor = {};
var cursor = db.collection(collectionName).aggregate([
{
$lookup: lookUpOption
},
{
$match: matchOption
}
],defCursor,null);
cursor.toArray(function(err, docs) {
console.log("Some data: ", docs);
callback(err, docs);
db.close();
});
}
那么你可以调用上面的函数:
function testAggregateLoad(someId, callback) {
var match = {
"localId": someId
};
var aggregateQuery = {
from: "someSecondCollectionName",
localField: "localId",
foreignField: "_id",
as: "someData"
};
getConnection(conCallBackEx);
function conCallBackEx(db) {
aggregateLoad(db, "someBaseLoadCollection", aggregateQuery, match, onSuccess);
}
function onSuccess(err, json) {
console.log('Loaded data is ', json);
callback(json);
}
}
function getConnection(callback) {
var MongoClient = require('mongodb').MongoClient;
return MongoClient.connect(url, function (err, db) {
if (null === err) {
callback(db, err);
} else {
console.log("failed to get db connection retrying " + err);
getConnection(callback);
}
});
}