【问题标题】:Looping through similar keys in node/jade循环遍历 node/jade 中的类似键
【发布时间】:2019-01-06 00:10:09
【问题描述】:

我有一组从 mongo 数据库返回的 mongoose 模型对象(使用 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


    【解决方案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"
        ]
      }
    ]
    

    【讨论】:

    • 看起来很有希望,我如何访问输出?像.find()这样的回调?
    • 是的,你需要使用callback or promise or async await
    • 我得到了一个 result 对象,但它有很多属性,我在其中找不到输出 - imgur.com/a/Omhw4tE
    • 它适用于 mongoplayground,但我不明白如何访问 node/mongoose 中的输出?
    • 你能把你的nodejs代码贴在你使用这个查询的地方吗
    【解决方案2】:

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

    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);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2021-11-28
      相关资源
      最近更新 更多