MongoError: can’t convert from BSON type string to Date in Meteor
MongoError: can’t convert from BSON type string to Date in Meteor
在 Meteor JS 中,我想找到生日为 today.I 的用户拥有这段代码,该代码在我的计算机(本地)上运行良好但在生产中失败:
let today = new Date()
let users = Meteor.users.find({
"status.lastLogin": { $not: { $eq: null } },
$expr: {
$and: [
{
$eq: [
{
$dayOfMonth: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
today.getDate(),
],
},
{
$eq: [
{
$month: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
today.getMonth() + 1,
],
},
],
},
})
我的服务器托管在 Galaxy 上,数据库托管在 mongodb.com
I checked the profile.birthdate type and it is Date on mongodb.com
错误是:
MongoError: can’t convert from BSON type string to Date\n at
Connection.
(/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/core/connection/pool.js:450:61)\n
at Connection.emit (events.js:311:20)\n at
Connection.EventEmitter.emit (domain.js:482:12)\n at processMessage
(/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/core/connection/connection.js:384:10)\n
at TLSSocket.
有谁知道为什么会这样,我该如何解决?
编辑:通过遵循@Jankapunkt 使用聚合的建议和阅读 ,我能够编写更好的(我认为...)查询和现在它正在工作。
这是新代码:
const today = new Date()
let users = Meteor.users.aggregate(
{
$project: {
status: "$status",
roles: "$roles",
month: {
$month: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
day: {
$dayOfMonth: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
},
},
{
$match: {
"status.lastLogin": { $ne: null },
roles: "candidate",
month: today.getMonth() + 1,
day: today.getDate(),
},
}
)
这里有几个问题,我想解决:
$expr
通常只在极少数情况下或与正则表达式匹配时才需要。
$dayOfMonth
是聚合运算符,在基本查询中不可用,但是有packages available
Meteor 通过 EJSON 内置了日期支持,它通过自定义类型扩展了 BSON(它为您抽象了类型转换):
Meteor.publish('allbirthdays', function () {
const today = new Date()
// correct timezone here
return Meteor.users.find({ '$profile.birthdate': today })
}
无需将 Date 转换为某些 mongo 运算符等
如果同一字段都需要不同的值,$and
是矛盾的(birthdate
永远不可能是一个月中的今天和今天),您是否打算使用$or
?
{ $not: { $eq: null } }
可以写成{ $ne: null }
如果您发布用户,请始终禁用 services
字段!服务包含(散列)密码和其他 oauth 提供程序,包括恢复令牌,这可能会导致严重的安全问题:
保存/查询没有聚合的日期
以上方法只允许精确的日期匹配,因为MongoDB只能通过aggregate
提供日期特定的查询。
因此,您的选择是:
A) 使用聚合包为 $month
和 $dayOfMonth
构建 $expr
,如您的示例代码
B) 仅将生日创建为语言环境字段(使其成为 String
类型):
export const getDate = () => {
// todo apply locale, timezone etc.
return new Date().toLocaleString(undefined, {
day: 'numeric', month: 'long'
})
}
并将其作为单独的字段保存在用户的集合中(例如birthDay
):
Meteor.users.update(userId, {
$set: {
'$profile.birthDay': getDate() // "June 3"
}
})
ans 查询仅针对这一天:
Meteor.publish('allbirthdays', function () {
const today = getDate()
return Meteor.users.find({ '$profile.birthDay': today })
}
- C) 将月份和日期保存为单独字段中的
Number
类型:
const today = new Date()
Meteor.users.update(userId, {
$set: {
'$profile.birthDay': today.getDate() // 3
'$profile.birthMon': today.getMonth() // 6
}
})
ans 查询仅针对这一天:
Meteor.publish('allbirthdays', function () {
const today = new Date()
return Meteor.users.find({
'$profile.birthDay': today.getDate()
'$profile.birthMon': today.getMonth()
})
})
在 Meteor JS 中,我想找到生日为 today.I 的用户拥有这段代码,该代码在我的计算机(本地)上运行良好但在生产中失败:
let today = new Date()
let users = Meteor.users.find({
"status.lastLogin": { $not: { $eq: null } },
$expr: {
$and: [
{
$eq: [
{
$dayOfMonth: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
today.getDate(),
],
},
{
$eq: [
{
$month: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
today.getMonth() + 1,
],
},
],
},
})
我的服务器托管在 Galaxy 上,数据库托管在 mongodb.com I checked the profile.birthdate type and it is Date on mongodb.com 错误是:
MongoError: can’t convert from BSON type string to Date\n at Connection. (/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/core/connection/pool.js:450:61)\n at Connection.emit (events.js:311:20)\n at Connection.EventEmitter.emit (domain.js:482:12)\n at processMessage (/app/bundle/programs/server/npm/node_modules/meteor/npm-mongo/node_modules/mongodb/lib/core/connection/connection.js:384:10)\n at TLSSocket.
有谁知道为什么会这样,我该如何解决?
编辑:通过遵循@Jankapunkt 使用聚合的建议和阅读
const today = new Date()
let users = Meteor.users.aggregate(
{
$project: {
status: "$status",
roles: "$roles",
month: {
$month: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
day: {
$dayOfMonth: {
date: "$profile.birthdate",
timezone: "Europe/Paris",
},
},
},
},
{
$match: {
"status.lastLogin": { $ne: null },
roles: "candidate",
month: today.getMonth() + 1,
day: today.getDate(),
},
}
)
这里有几个问题,我想解决:
$expr
通常只在极少数情况下或与正则表达式匹配时才需要。$dayOfMonth
是聚合运算符,在基本查询中不可用,但是有packages availableMeteor 通过 EJSON 内置了日期支持,它通过自定义类型扩展了 BSON(它为您抽象了类型转换):
Meteor.publish('allbirthdays', function () {
const today = new Date()
// correct timezone here
return Meteor.users.find({ '$profile.birthdate': today })
}
无需将 Date 转换为某些 mongo 运算符等
-
如果同一字段都需要不同的值,
$and
是矛盾的(birthdate
永远不可能是一个月中的今天和今天),您是否打算使用$or
?{ $not: { $eq: null } }
可以写成{ $ne: null }
如果您发布用户,请始终禁用
services
字段!服务包含(散列)密码和其他 oauth 提供程序,包括恢复令牌,这可能会导致严重的安全问题:
保存/查询没有聚合的日期
以上方法只允许精确的日期匹配,因为MongoDB只能通过aggregate
提供日期特定的查询。
因此,您的选择是:
A) 使用聚合包为
$month
和$dayOfMonth
构建$expr
,如您的示例代码B) 仅将生日创建为语言环境字段(使其成为
String
类型):
export const getDate = () => {
// todo apply locale, timezone etc.
return new Date().toLocaleString(undefined, {
day: 'numeric', month: 'long'
})
}
并将其作为单独的字段保存在用户的集合中(例如birthDay
):
Meteor.users.update(userId, {
$set: {
'$profile.birthDay': getDate() // "June 3"
}
})
ans 查询仅针对这一天:
Meteor.publish('allbirthdays', function () {
const today = getDate()
return Meteor.users.find({ '$profile.birthDay': today })
}
- C) 将月份和日期保存为单独字段中的
Number
类型:
const today = new Date()
Meteor.users.update(userId, {
$set: {
'$profile.birthDay': today.getDate() // 3
'$profile.birthMon': today.getMonth() // 6
}
})
ans 查询仅针对这一天:
Meteor.publish('allbirthdays', function () {
const today = new Date()
return Meteor.users.find({
'$profile.birthDay': today.getDate()
'$profile.birthMon': today.getMonth()
})
})