Статьи

Использование MongoDB Aggregation Framework для фильтрации карт Trello

Когда я помогал подготовиться к конференции CFSummit, мы организовали сессии по Trello и провели публичное голосование.

В расписании конференции важно знать, какие сессии будут популярны. Желательно, чтобы самые желательные сеансы не конкурировали друг с другом. Таким образом, я хотел вытянуть сессии и организовать сессии по популярности.

Структура агрегирования MongoDB

Структура агрегирования MongoDB является относительно новым дополнением к платформе. Используя эту платформу, вы можете группировать, сортировать, рассчитывать и обрабатывать сбор информации в совокупном смысле. Вот как я это сделал для данных Trello JSON.

Монго Запрос

Экспорт из Trello дает большой документ JSON с членами JSON для каждой карты. Оказывается, в нашем случае все карты, которые мы хотим, принадлежат определенному списку. Как только мы вытащим правильные карточки, мы хотим отсортировать их по голосам. Мы получим отсортированный массив сессий по популярности. Вот запрос MongoDB:

db.cfsummit.aggregate([
    {$project: { "cards": "$cards"}},
    {$unwind: "$cards"},
    {$match: {"cards.idList": {"$in": ["51c9aa15d0b4871a3e000075"]}}},
    {$project: {"_id": 1, "name": "$cards.name", "members": "$cards.idMembers", "url": "$cards.url", "votes": "$cards.badges.votes"}},
    {$sort: {votes:-1}}
])

Объяснил построчно:

db.cfsummit.aggregate ([

Заметьте, что аргумент к агрегатной команде является массивом? Это означает, что вы можете организовать серию преобразований документов в шаги. Каждый шаг будет каким-то образом манипулировать документом. Давайте посмотрим на наш первый шаг в преобразовании:

{$ project: {«cards»: «$ cards»}},

Первое преобразование — это команда $ project. Проект (Pro-JECT) , означает проект нового способа просмотра данных. В этом случае меня интересует только узел карточек. Результатом этого документа является новый документ, в котором в основном только член карты. Вы можете писать запросы без $ project, но я всегда использую его по двум причинам. Во-первых, уменьшение размера рабочего документа делает запрос более эффективным. Полученный проецируемый документ меньше по размеру, и им легче манипулировать. Вторая причина — я пишу свои запросы постепенно, поэтому мне нужно только увидеть то, что мне нужно увидеть. (Обратите внимание, что член карты является массивом, это важно на следующем шаге)

 view formatted print about
"result" : [
    {
        "_id" : ObjectId("51ee98afaa17829291af81e0"),
        "cards" : [
            {
                "id" : "51b0fbec94b2237145005a18",
                "badges" : {
                    "votes" : 0,
                    "viewingMemberVoted" : false,
                    "subscribed" : false,
.....

{$ unwind: «$ cards»},

Теперь узлы карты — это массив. Я хочу отсортировать все подходящие карточки по параметру голосования. Я использую команду $ unwind для преобразования членов массива карт в их собственные документы.

"result" : [
    {
        "_id" : ObjectId("51ee98afaa17829291af81e0"),
        "cards" : {
            "id" : "51b0fbec94b2237145005a18",
            "badges" : {
                "votes" : 0,
                "viewingMemberVoted" : false,
                "subscribed" : false,
...

Обратите внимание, что член карт больше не является массивом … это важно для группировки, что мы и сделаем позже.

{$ match: {«cards.idList»: {«$ in»: [«51c9aa15d0b4871a3e000075»]}}}

Каждая из карт, с которыми мы хотим иметь дело, принадлежит listId: 51c9aa15d0b4871a3e000075. Поэтому мы используем команду $ match, чтобы сопоставить карточки с искомым идентификатором listId. (Думайте об этом как о предложении where в SQL, если это ваш фон.

"result" : [
    {
        "_id" : ObjectId("51ee98afaa17829291af81e0"),
        "cards" : {
            "id" : "51b0fbec94b2237145005a18",
            "badges" : {
                "votes" : 0,
                "viewingMemberVoted" : false,
                "subscribed" : false,
...

{$ project: {«_id»: 1, «name»: «$ cards.name», «members»: «$ cards.idMembers», «url»: «$ cards.url», «voice»: «$ cards.badges.votes «}},

Теперь у меня есть отсортированные карты, принадлежащие правильному списку. Теперь я хочу настроить структуру возвращаемых данных наиболее удобным для меня способом. В моем случае мне нужны идентификатор, название сессии, докладчики, URL Trello для карты и полученные голоса. Мы снова используем команду $ project для организации данных в нужном нам формате. Обратите внимание, что я использовал путь с разделителями в виде точки, чтобы пройти дерево JSON к нужному элементу данных. Следовательно, голоса находились в узле голосования, который находится внутри узла значков, который находится внутри узла карточек.

{$ sort: {голосов: -1}}

Наконец, нам нужно отсортировать карты по популярности. Команда $ sort принимает объект JSON, содержащий узлы, по которым вы хотите отсортировать. Мы хотим, чтобы большинство голосов отображалось первым, поэтому мы присваиваем -1 столбцу голосов для сортировки по убыванию. Если изменить это значение на 1, данные будут отсортированы по возрастанию.

])

Не забудьте закрыть массив конвейера агрегации и закрыть скобки функции.

Итоговый результат данных

{
    "result" : [
        {
            "_id" : "51ee98afaa17829291af81e0",
            "name" : "Security Best Practices",
            "members" : [
                "51b0ff9bf9d2b2b94c0027bd"
            ],
            "url" : "https://trello.com/c/ITpzm0xS/15-security-best-practices",
            "votes" : 45
        },
        {
            "_id" : "51ee98afaa17829291af81e0",
            "name" : "ColdFusion Object Oriented Advanced",
            "members" : [
                "519a266b522736c97000a224"
            ],
            "url" : "https://trello.com/c/1DV4Ud2Z/41-coldfusion-object-oriented-advanced",
            "votes" : 43
        },
        {
            "_id" : "51ee98afaa17829291af81e0",
            "name" : "REST 101",
            "members" : [
                "50997edfdcb1ac3f1c00ac66"
            ],
            "url" : "https://trello.com/c/1oYg37pV/23-rest-101",
            "votes" : 34
        },
....

Хотите больше информации?

Узнайте больше о платформе агрегации MongoDB на их сайте документации. Вы можете установить MongoDB за очень короткое время и начать работать с данными.

Бесплатное обучение

Если вы хотите более структурированное обучение, 10Gen предлагает 7-недельный онлайн-курс обучения на MongoDB бесплатно. Занятия очень хорошо сделаны. Рассмотрим класс, если вы любитель монго.