循环通过node / jade中的类似键

问题描述 投票:1回答:2

我有一组mongoose模型对象从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}

在迭代数组时,我有什么问题吗?

或者有一种方法可以将数组直接从数据库转换为对象,如:

{
    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: , …}
arrays node.js mongodb mongoose pug
2个回答
1
投票

你可以尝试下面的$group$push聚合

首先你需要$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
投票

您可以将您拥有的数据结构转换为您想要的数据结构:

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);
© www.soinside.com 2019 - 2024. All rights reserved.