4

У меня есть документ mongo, содержащий массив строк, и мне нужно преобразовать этот конкретный массив строк в массив объектов, содержащий пару ключ-значение. Ниже приведена моя точная оценка.Преобразование массива mongo в объект с помощью пары ключ-значение

{ 
    "_id" : ObjectId("57e3720836e36f63695a2ef2"), 
    "platform" : "A1", 
    "available" : { 
     "Community" : { 
      "attributes" : { 
       "type" : { 
        "values" : [ 
         "well-known", 
         "simple", 
         "complex" 
        ], 
        "defaultValue" : "well-known" 
       }, 
[......] 


} 

Текущий запрос:

templateAttributes.find({platform:"V1"}).map(function(c){ 
    //instantiate a new array 
    var optionsArray = []; 
for (var i=0;i< c['available']['Community']['attributes']['type']['values'].length; i++){ 
    optionsArray[i] = {};    // creates a new object 
    optionsArray[i].label = c['available']['Community']['attributes']['type']['values'][i]; 
    optionsArray[i].value = c['available']['Community']['attributes']['type']['values'][i]; 
    } 
    return optionsArray; 
})[0]; 

Результат:

[{label:"well-known", value:"well-known"}, 
{label:"simple", value:"simple"}, 
{label:"complex", value:"complex"}] 

Является ли мой подход достаточно эффективно, или есть способ оптимизировать выше запрос, чтобы получить то же самое желаемый результат?

+0

Любые конкретные причины, которые это необходимо сделать на стороне монгодба? –

+0

Нет. Нет конкретной причины, по которой это нужно сделать на стороне монго. Поскольку я использую это в Meteor, этот запрос запускается в памяти (mini-mongo). – blueren

+0

@ bluereen Ok. Тогда агрегат - это решение. Просто имейте в виду, что '$ unwind' будет умножать размер набора результатов array.length раз. Поэтому используйте '$ project', чтобы просто сохранить необходимые поля, возможно, только« значения ». –

ответ

3

Не уверен, что вы хотите сделать с конечным результатом, как ключи и значения так же. Тем не менее, вы можете использовать структуру агрегации , где вы можете денормализовать массив встроенных значений, используя оператор , который сглаживает его, то есть создает копию каждого документа на запись в массив.

После выравнивания массива значений вы можете применять операторы накопления $group значений, чтобы их заполнить. Конечный трубопровод оператора $project сформировал бы поля из предыдущей группировки в желаемый формат.

Следуйте этот пример, чтобы получить понятие:

templateAttributes.aggregate([ 
    { "$match": { "platform": "V1" } }, 
    { "$unwind": "$available.Community.attributes.type.values" }, 
    { 
     "$group": { 
      "_id": "$available.Community.attributes.type.values", 
      "value": { "$first": "$available.Community.attributes.type.values" } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "label": "$_id", 
      "value": 1 
     } 
    } 
]) 

Поскольку вы используете Метеор, метеор добавить meteorhacks:aggregate добавят надлежащую поддержку агрегации для Метеора, так что вы можете запустить выше трубопровод агрегации на вашей коллекции.

+0

Я намерен передать их в меню HTML . Благодаря! – blueren

+1

Спасибо, Крис. Я все еще обсуждаю пакет и весь запрос aggegate, поскольку пакет только делает вещи на стороне сервера. Кроме того, я использую автоформы и подачу выпадающих данных из запроса mongo на стороне клиента – blueren

3

Пожалуйста, используйте здесь агрегацию.

db.templateAttributes.aggregate([ 
            {"$match":{platform:"A1"}}, {"$unwind": "$available.Community.attributes.type.values"}, 
            {$group: {"_id": null, "val":{"$push":{label:"$available.Community.attributes.type.values", 
                      value:"$available.Community.attributes.type.values"}}}} 
           ]).toArray()[0].val 

Выход:

[ 
    { 
      "label" : "well-known", 
      "value" : "well-known" 
    }, 
    { 
      "label" : "simple", 
      "value" : "simple" 
    }, 
    { 
      "label" : "complex", 
      "value" : "complex" 
    } 
] 
+1

Спасибо. Я сделаю это и вернусь. – blueren

0

Используйте запрос

templateAttributes.aggregate([{ 
$match: { 
    "platform" : "A1" 
    }}, 
    { 
    $unwind: {path : "$available.Community.attributes.type.values"}},{ $group:{ 
    _id:"$_id", 
    result:{ 
     $push: { 
      label: "$available.Community.attributes.type.values", value: "$available.Community.attributes.type.values" 
      } 
     } 
    }}]) 

Это даст вам точный ваш ожидаемый ответ.

 Смежные вопросы

  • Нет связанных вопросов^_^