我有一个REST方法应该返回一个 JSON数组,其中包含从mongodb读取的某些元素(使用mongoose). 它应该非常简单(在实际情况下,find方法有参数,但这不是问题): OutDataModel.find().stream({transform: JSON
它应该非常简单(在实际情况下,find方法有参数,但这不是问题):
OutDataModel.find().stream({transform: JSON.stringify}).pipe(res);
这种方法的问题是我没有得到有效的JSON,因为结果是这样的:
{"id":"1","score":11}{"id":"2","score":12}{"id":"3","score":13}
我期待着这个:
[{"id":"1","score":11},{"id":"2","score":12},{"id":"3","score":13}]
我一直无法找到解决方案,但我很确定会有一个简单的解决方案.
我尝试过的:
没有什么我为此感到自豪,但在这里它.
>在流式传输之前写'[‘到响应.
>而不是JSON.stringify我提供了另一个调用JSON.stringify的方法,最后添加了一个’,’
>在流的’end’事件中,我将’]’写入响应.
仍然没有使用这个“解决方案”,因为我最后有一个尾随的逗号,如下所示:
[{"id":"1","score":11},{"id":"2","score":12},{"id":"3","score":13},]
正如我所说,我很确定应该有一个干净的解决方案,因为它应该是非常常见的.
这个方法会有很多并发调用,因此我不想将所有内容都读入内存,然后将所有内容写入响应.每个调用都不会返回很多记录,但所有这些记录都可能很大.使用者是一个带有spring的java应用程序,使用jackson来解析JSON.
请让我知道怎么做.
回答
我通过按照接受的答案中的建议创建了一个转换流来实现它.
我的流看起来像这样:
var arraystream = new stream.Transform({objectMode: true}); arraystream._hasWritten = false; arraystream._transform = function (chunk, encoding, callback) { console.log('_transform:' + chunk); if (!this._hasWritten) { this._hasWritten = true; this.push('[' + JSON.stringify(chunk)); } else { this.push(',' + JSON.stringify(chunk)); } callback(); }; arraystream._flush = function (callback) { console.log('_flush:'); this.push(']'); callback(); };
以及使用它的代码:
OutDataModel.find().stream().pipe(arraystream).pipe(res);
谢谢.
通过实施自己的逻辑,你走在正确的轨道上.你也可以在这里使用ArrayFormatter做类似的事情: https://gist.github.com/aheckmann/1403797转换函数分别在每个文档上调用 – 一个Mongoose QueryStream每个’data’事件发出一个文档,但是QueryStream没有在语义上将它们视为任何更大的数组数据结构的一部分;要获得一个数组格式的JSON,你真的必须自己做(如你所推测的那样).