如何从mongodb查询直接返回原始JSON ?



在MongoDB中(使用mongosh或命令行mongo cli),您可以查询文档,例如使用db.mycollection.find({"something":true})并得到以下结果:

{
"someDate": ISODate("2022-10-24T17:21:44.980Z"),
"something": true,
"hello": "world"
}

这个结果,然而,不是有效的JSON(由于ISODate)。我如何改变上面的查询,使MongoDB返回规范(有效)JSON?

我正在寻找一种递归和通用的方法来做到这一点,即使是深度嵌套的文档。

有许多现有的答案,我将澄清几个:

使用聚合生成JSON格式的输出:操场上

db.collection.aggregate([
{
$match: {
something: true
}
},
{
$project: {
_id: 1,
someDate: {
$dateToString: {
format: "%Y-%m-%dT%H:%M:%S:%LZ",
date: "$someDate"
}
},
something: 1,
hello: 1
}
}
])

在应用程序中遍历查询:(例子,node . js)

db.mycollection.find({"something":true}).forEach(function(doc) {   
doc.someDate = doc.someDate.toISOString() // or even .toJSON()
})
// Or with await
const records = await db.mycollection.find({"something":true}).map(doc => {
doc.someDate = doc.someDate.toISOString()
return doc
}).toArray()

你运行这个命令的细节是非常重要的,你能分享这些吗?

猜测您可能正在通过(较旧的)mongo实用程序(而不是较新的mongosh)运行此程序。但是确认这一点,以及您正在使用的数据库版本,都是有帮助的。为了回答这个问题,我将保留这个假设。

这个结果,然而,不是有效的JSON(由于ISODate)。

数据库本身不返回具有ISODate的文本。事实上,它没有返回或"说话"。JSON。相反,数据库通过"二进制json"进行通信。简称BSON。事实上,MongoDB使用BSON还是JSON?"本页的部分特别提到了以下内容:

首先,BSON文档可能包含Date或Binary对象,这些对象在纯JSON中是无法原生表示的。

所以当你看到像ISODate()这样的东西时,那就是客户端应用程序包装并以更有限的(基于文本的)类似json的形式表示丰富的BSON文档。重要的是,这通常是出于可读性的目的。您应该能够直接在应用程序中传递和操作数据库返回的信息(文档),而无需进行任何类型的转换,也不会丢失丰富的类型信息。关于BSON的其他阅读材料在这里。

回到最初的问题,如果您想让shell打印出有效的JSON文档,那么可以通过额外的帮助程序来实现。在较旧的mongo实用程序中,问题中描述的情况的再现是:

> db.mycollection.findOne({"something": true})
{
"_id" : 1,
"someDate" : ISODate("2022-11-30T14:38:37.711Z"),
"something" : true,
"hello" : "world"
}

shell本身可以理解并操作ISODate()(以及其他类似的函数)。如果您出于某种原因想要删除ISODate()之类的内容,那么您可以利用JSON.stringify()功能(为了可读性,使用行缩进重新格式化):

> JSON.stringify( db.mycollection.findOne({"something": true}) )
{
"_id":1,
"someDate":"2022-11-30T14:38:37.711Z",
"something":true,
"hello":"world"
}

新的mongoshshell在这里提供了更多的实用程序:

> EJSON.serialize( db.mycollection.findOne() )
{
_id: 1,
someDate: { '$date': '2022-11-30T14:38:37.711Z' },
something: true,
hello: 'world'
}

通过这些EJSON函数,mongosh在以这种格式打印数据时试图保留类型信息。请注意,在前面的示例中,日期只是表示为字符串,但这里shell使用Extended JSON来捕获someDate的类型是date的事实。

相关内容

  • 没有找到相关文章

最新更新