我遇到运行以下聚合查询的问题:
db.snippets.aggregate([ { '$project': { month: { '$month': '$created_at' }} } ])
相同的错误消息是:
assert: command failed: {
"errmsg" : "exception: can't convert from BSON type EOO to Date",
"code" : 16006,
"ok" : 0 } : aggregate failed
我如何解决这个问题。我找到了一个相关的问题
Related Stack Overflow question
但它并没有说明如何完成任务。
答案 0 :(得分:57)
您可能有一个或多个created_at
值不是BSON Date
的文档,您需要通过将这些值转换为{{1}来解决这个问题。或者删除它们。
您可以找到使用Date
运算符$not
运算符的文档,如:
db.snippets.find({created_at: {$not: {$type: 9}}})
如果created_at
值是日期字符串,您可以找到需要更新的文档,然后使用以下代码在shell中更新它们:
db.snippets.find({created_at: {$not: {$type: 9}}}).forEach(function(doc) {
// Convert created_at to a Date
doc.created_at = new Date(doc.created_at);
db.snippets.save(doc);
})
答案 1 :(得分:4)
在某些情况下,某些文档应该具有空日期字段。在这些情况下,您可以尝试这个(使用您的示例):
db.snippets.aggregate([ { '$project': { month:
{ $cond: [{ $ifNull: ['$created_at', 0] }, { $month: '$created_at' }, -1] }} } ])
在这个例子中,在没有字段' $ created_at'的情况下,我们会得到-1。找到了。对于所有其他情况,我们将获得日期月。
答案 2 :(得分:2)
我有一个相关的问题,但在我的情况下,Date字段是数组的成员,因此错误是"无法将BSON类型的对象转换为Date"。
我需要从possibleTripDateTimes数组中的日期获取星期几。
示例文件:
{
"possibleTripDateTimes" : [
{
"tripDateTime" : ISODate("2015-08-01T06:00:00.000-0700")
}
]
}
修复只是使用点表示法来处理数组成员字段。
db.trips.aggregate([
{
$project: {
departTime: {
$map: {
input: "$possibleTripDateTimes.tripDateTime",
as: "dateTime",
in: { $dayOfWeek: "$$dateTime" }
}
}
}
}
]
);
我希望这可以帮助那些在" BSON类型对象"上获得零搜索结果的人。搜索
答案 3 :(得分:1)
尝试这个,它对我的帮助超出了问题。
db.snippets.aggregate([{
'$project': {
month: { $substr: ["$created_at", 5, 2] }
}
}]);
上面的代码得到了明智的
数据以ISO格式输入数据库,然后可以轻松使用。
答案 4 :(得分:1)
我遇到了类似的问题,并解决了检查日期是否存在的问题。
db.users.aggregate([
{$project:{day: { $cond: ["$bd", { $dayOfMonth: "$bd" }, -1] },
month: { $cond: ["$bd", { $month: "$bd" }, -1] },
year: { $cond: ["$bd", { $year: "$bd" }, -1] }
}},
{$match:{"month":1, "day":15}}
])
我的约会字段为bd
,并且我将收到所有在1月15日过生日的用户。
答案 5 :(得分:1)
我遇到了同样的问题,我认为导致转换失败的某些文档缺少日期字段。我刚刚添加了一个匹配子句来过滤掉这些。但当然,我正在调查我的应用程序方面为什么他们没有被填充。
render()
答案 6 :(得分:0)
如果您在聚合中错误地命名了相对于数据库中属性的属性,也会出现此错误。
例如我的代码是
$group: {
_id: {$week: "$projects.timeStamp"},
total: { $sum: "$projects.hours" }
}
但我没有在我的数据库中添加时间戳,所以只需修改为projects.timestamp
修复它。
答案 7 :(得分:0)
首先,您需要检查数据类型是否在ISODate中。如果不是,则可以按照以下示例更改数据类型。
db.collectionName.find().forEach(function(each_object_from_collection){each_object_from_collection.your_date_field=new ISODate(each_object_from_collection.your_date_field);db.collectionName.save(each_object_from_collection);})
现在您可以通过两种方式找到它
db.collectionName.find({ $expr: {$eq: [{ $year: "$your_date_field" }, 2017]}});
或通过汇总
db.collectionName.aggregate([{$project: {field1_you_need_in_result: 1,field12_you_need_in_result: 1,your_year_variable: {$year: '$your_date_field'}, your_month_variable: {$month: '$your_date_field'}}},{$match: {your_year_variable:2017, your_month_variable: 3}}])