【发布时间】:2019-08-26 13:21:13
【问题描述】:
我将来自 MongoDB 的查询结果作为包含嵌套子文档和子文档数组的文档数组。
[
{
RecordID: 9000,
RecordType: 'Item',
Location: {
_id: 5d0699326e310a6fde926a08,
LocationName: 'Example Location A'
}
Items: [
{
Title: 'Example Title A',
Format: {
_id: 5d0699326e310a6fde926a01,
FormatName: 'Example Format A'
}
},
{
Title: 'Example Title B',
Format: {
_id: 5d0699326e310a6fde926a01,
FormatName: 'Example Format B'
}
}
],
},
{
RecordID: 9001,
RecordType: 'Item',
Location: {
_id: 5d0699326e310a6fde926a08,
LocationName: 'Example Location C'
},
Items: [
{
Title: 'Example Title C',
Format: {
_id: 5d0699326e310a6fde926a01,
FormatName: 'Example Format C'
}
}
],
}
]
问题
我需要按列顺序将结果导出到 XLSX。 XLSX 库仅用于导出 顶级 属性(例如 RecordID 和 RecordType)。我还需要导出嵌套对象和对象数组。给定属性名称列表,例如RecordID, RecordType, Location.LocationName, Items.Title, Items.Format.FormatName 属性必须按指定顺序导出到 XLSX 列。
想要的结果
这是所需的“扁平化”结构(或类似结构) 我认为应该能够转换为 XLSX 列。
[
{
'RecordID': 9000,
'RecordType': 'Item',
'Location.LocationName': 'Example Location A',
'Items.Title': 'Example Title A, Example Title B',
'Items.Format.FormatName': 'Example Format A, Example Format B',
},
{
'RecordID': 9001,
'RecordType': 'Item',
'Location.LocationName': 'Example Location C',
'Items.Title': 'Example Title C',
'Items.Format.FormatName': 'Example Format C',
}
]
我正在使用 XLSX 库将查询结果转换为仅适用于顶级属性的 XLSX。
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(results.data);
const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const data: Blob = new Blob([excelBuffer], { type: EXCEL_TYPE });
FileSaver.saveAs(data, new Date().getTime());
可能的选择
我猜我需要在查询中使用聚合或在返回查询时执行后处理来“展平”结构。
选项 1:在 MongoDB 查询中构建逻辑以展平结果。
$replaceRoot 可能会起作用,因为它能够“将现有的嵌入文档提升到顶层”。虽然我不确定这是否能完全解决问题,但我不想在原地修改文档,我只需要将结果展平以便导出。
这是我用来生成结果的 MongoDB 查询:
records.find({ '$and': [ { RecordID: { '$gt': 9000 } } ]},
{ skip: 0, limit: 10, projection: { RecordID: 1, RecordType: 1, 'Items.Title': 1, 'Items.Location': 1 }});
选项 2:在节点服务器上迭代和展平结果
这可能不是性能最高的选项,但如果我在 MongoDB 查询中找不到这样做的方法,它可能是最简单的。
更新:
我也许可以使用 MongoDB 聚合 $project 来“展平”结果。例如,这个聚合查询通过“重命名”属性有效地“扁平化”了结果。我只需要弄清楚如何在聚合操作中实现查询条件。
db.records.aggregate({
$project: {
RecordID: 1,
RecordType: 1,
Title: '$Items.Title',
Format: '$Items.Format'
}
})
更新 2:
我已经放弃了 $project 解决方案,因为我需要更改整个 API 以支持聚合。另外,我需要为填充找到一个解决方案,因为聚合不支持它,相反,它使用 $lookup 是可能的,但很耗时,因为我需要动态编写查询。我将回过头来研究如何通过创建一个函数来递归地迭代对象数组来展平对象。
【问题讨论】:
-
您能否发布您想要输出为 excel 文件的有效数据样本?您添加的 blob 有语法错误
-
@Peter 使用有效语法更新了所需的“扁平化”结构。
标签: node.js excel mongodb xlsx