2015-09-29 2 views
2

Я пытаюсь использовать underscore.js в проекте Meteor, над которым я работаю, но не могу понять, как преобразовать набор объектов.underscore.js - создать массив уникальных элементов из объектов, встроенных в список объектов

объекты выглядеть примерно так (есть около 15k, но все они выглядят как эти два):

[{ 
 
    "_id": "a_0011223344", 
 
    "taggedUsers": [{ 
 
    "id": 1122244453, 
 
    "username": "john123" 
 
    }], 
 
    "field": "ABC" 
 
}, { 
 
    "_id": "a_0011223345", 
 
    "taggedUsers": [{ 
 
    "id": 1122244454, 
 
    "username": "bill123" 
 
    }, { 
 
    "id": 1122244455, 
 
    "username": "jim123" 
 
    }], 
 
    "field": "ABC" 
 
}]

Каждый объект может иметь один или несколько "taggedUsers" объектов, и мне нужно список уникальных полей "taggedUsers.username". Meteor не поддерживает функцию distinct mongoDB, поэтому я пытаюсь использовать underscore.js вместо (за то, что я прочитал, и рекомендацию в this post).

В моей боковой консоли сервера db.myCollection.distinct("taggedUsers.username") возвращает желаемый результат ["john123", "bill123", "jim123"], но я не могу воспроизвести его в underscore.js.

Я пытался комбинацию _.each, _.map, _.pluck и _.uniq, но не увенчались успехом. Я думаю, что это может иметь что-то, что поля находятся во встроенных объектах, но я не уверен.

В идеале я хотел бы вернуть массив объектов, глядя, как это:

[{ 
 
    "id": 1122244453, 
 
    "username": "john123", 
 
    "field": "ABC" 
 
}, { 
 
    "id": 1122244454, 
 
    "username": "bill123", 
 
    "field": "ABC" 
 
}, { 
 
    "id": 1122244455, 
 
    "username": "jim123", 
 
    "field": "DEF" 
 
}]
с только taggedUsers.username, taggedUsers.id и field feilds, и все дубликаты удалены, но был бы рад, если бы я может также просто получить массив taggedUsers.usernames, как и я в функции db.colleciton.distinct().

В конечном счете было бы неплохо узнать, как получить базовый массив, массив уникальных объектов (или, может быть, даже получить результат db.collection.distinct() в помощнике шаблона), но любая помощь или точка в правой направление было бы признателен!

+0

Вы хотите массив помеченных пользователей, но этот пример показывает, что у вас также есть 'поле: ABC' в них. Это опечатка? –

+0

«Поле» в родительском объекте тоже было бы полезно, позвольте мне изменить вопрос, чтобы сделать его более понятным. @DavidWeldon – pingo

+0

@DavidWeldon Рекомендуем ли вы найти решение underscore.js, или я должен попытаться запустить запрос mongo на сервере и вызов его методом? – pingo

ответ

2

Основываясь на нашем разговоре, кажется, что было бы лучше вычислить это на сервере посредством вызова метода. Для образовательных целей, вот как вы могли бы сделать это с помощью подчеркивания:

// Get an array of docs somehow 
var docs = Collection.find().fetch(); 

var taggedUsers = _.chain(docs) 
    .map(function(d) { 
    // Copy the 'field' to each of the tagged users within a doc 
    _.each(d.taggedUsers, function(user) { 
     user.field = d.field; 
    }); 
    return d; 
    }) 
    .pluck('taggedUsers') // Extract only the tagged users arrays 
    .flatten() // Flatten them into a single array 
    .value(); 

// taggedUsers could look something like: 
// [ { id: 1122244453, username: 'john123', field: 'ABC' }, 
// { id: 1122244454, username: 'bill123', field: 'ABC' }, 
// { id: 1122244455, username: 'jim123', field: 'ABC' }, 
// { id: 1122244453, username: 'john123', field: 'ABC' } ] 

// Compute a unique lists of tagged users, where the docs are unique by id 
var utu = _.uniq(taggedUsers, false, function(user) {return user.id;}); 
+0

Спасибо, что это правильный подход с подчеркиванием, но моя консоль возвращает 'taggedUsers' и' utu' как пустые массивы. Мой запрос выглядит так: 'Collection.find ({" taggedUsers ": {" $ exists ": true}}, {fields: {_id: 1, field: 1," taggedUsers.username ": 1," taggedUsers.id ": 1}}). Fetch();' если это помогает.Я думаю, что ошибка имеет какое-то отношение к цитатам вокруг «taggedUsers.id» и «taggedUsers.username» ', но может быть неправильной. – pingo

+0

Убедитесь, что 'docs' что-то в нем. Я проверил код с приведенными вами примерами, и он сработал. Возможно, просто попробуйте 'var docs = Collection.find ({taggedUsers: {$ exists: true}}). Fetch()'. (при условии, что 'Collection' заменяется вашим фактическим именем коллекции). –

+0

Выглядит так: http://imgur.com/55tYWnz. Очевидно, не думайте, что ваше решение не работает, но я не уверен, что мне не хватает. «Поле» должно быть полем «поле» (т. е. ABC, DEF) или способом получения значений для 'user' и' d'? Кроме того, что означает 'd'? Благодаря! – pingo

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