我有一个从mongo数据库返回的猫鼬模型对象数组(使用Model.find()
):
[
{_id: '...', type: 'colour', value: 'red'},
{_id: '...', type: 'colour', value: 'blue'},
{_id: '...', type: 'material', value: 'steel'},
{_id: '...', type: 'colour', value: 'green'},
{_id: '...', type: 'material', value: 'wood'},
{_id: '...', type: 'material', value: 'plastic'}
]
类型未知,值未知。
我要为每种类型创建下拉列表,并填充该类型的值:
<select id="colour" name="colour">
<option value="abc123">red</option>
<option value="abc124">blue</option>
<option value="abc125">green</option>
</select>
<select id="material" name="material">
<option value="abc123">steel</option>
<option value="abc124">wood</option>
<option value="abc125">plastic</option>
</select>
当前,我正在使用type
作为数组键将对象数组转换为多维数组:
let facets = [];
for (var f in dbfacets) {
if (f != '0'){
if (dbfacets[f].type in facets) {
facets[dbfacets[f].type].push(dbfacets[f].name);
} else {
facets[dbfacets[f].type] = [];
facets[dbfacets[f].type].push(dbfacets[f].name);
}
}
}
这似乎可行,但是在Jade中使用时,它会跳过facets
对象,就好像它没有成员一样(尽管正在填充facets对象):
each fac, index in facets
select(name='#{index}', id='#{index}')
each f in fac
option(value='#{f._id}') #{f.name}
在遍历数组时是否做错了什么?
或者,有一种方法可以将数组直接从DB转换为类似这样的对象:
{
type: 'colour',
vals: {
'red',
'green',
'blue'
}
},
{
type: 'material',
vals: {
'steel',
'wood',
'plastic'
}
}
通话总量
Facet.collection.aggregate([
{
'$group': {
'_id': '$type',
'vals': {
'$push': '$value'
}
}
},
{
'$project': {
'vals': 1,
'type': '$_id',
'_id': false
}
}
], (err, result) => {
if (err){return next(err);}
console.log(result);
});
这给了我输出:
result
AggregationCursor {pool: null, server: null, disconnectHandler: Store, bson: BSON, ns: "toylib.facets", …}
_events:Object {}
_eventsCount:0
_maxListeners:undefined
_readableState:ReadableState {objectMode: true, highWaterMark: 16, buffer: BufferList, …}
bson:BSON {}
cmd:Object {aggregate: "facets", pipeline: Array(2), cursor: Object}
cursorState:Object {cursorId: null, cmd: Object, documents: Array(0), …}
destroyed:false
disconnectHandler:Store {s: Object, length: <accessor>}
domain:null
logger:Logger {className: "Cursor"}
ns:"toylib.facets"
options:Object {readPreference: null, cursor: Object, promiseLibrary: , …}
pool:null
readable:true
readableHighWaterMark:16
s:Object {maxTimeMS: null, state: 0, streamOptions: Object, …}
server:null
sortValue:undefined
topology:Server {domain: null, _events: Object, _eventsCount: 26, …}
__proto__:Readable {_next: , setCursorBatchSize: , cursorBatchSize: , …}
答案 0 :(得分:1)
首先,您需要$group
的type
字段,然后是$push
,它返回一个值数组,这些值是通过将表达式应用于$group
中的每个文档而得出的>
Facet.aggregate([
{
"$group": {
"_id": "$type",
"vals": {
"$push": "$value"
}
}
},
{
"$project": {
"vals": 1,
"type": "$_id",
"_id": false
}
}
]).then((result) => {
console.log(result)
})
输出
[
{
"color": "material",
"vals": [
"steel",
"wood",
"plastic"
]
},
{
"color": "colour",
"vals": [
"red",
"blue",
"green"
]
}
]
答案 1 :(得分:1)
您可以像这样将所需的数据结构转换为所需的数据结构:
let data = [
{_id: '...', type: 'colour', value: 'red'},
{_id: '...', type: 'colour', value: 'blue'},
{_id: '...', type: 'material', value: 'steel'},
{_id: '...', type: 'colour', value: 'green'},
{_id: '...', type: 'material', value: 'wood'},
{_id: '...', type: 'material', value: 'plastic'}
]
// build a temp object whose keys are the types
// and the data is an array of values for that type
let temp = new Map();
for (let item of data) {
let type = item.type;
let array = temp.get(type);
if (!array) {
array = [];
temp.set(type, array);
}
array.push(item.value);
}
// convert that to your final requested format, an array of objects
let results = [];
for (let [type, vals] of temp) {
results.push({type, vals});
}
console.log(results);