Как выполнить эквивалент SQL Join в MongoDB?

424

Как выполнить эквивалент SQL Join в MongoDB?

Например, у вас есть две коллекции (пользователи и комментарии), и я хочу вывести все комментарии с помощью pid = 444 вместе с информацией пользователя для каждого.

comments
  { uid:12345, pid:444, comment="blah" }
  { uid:12345, pid:888, comment="asdf" }
  { uid:99999, pid:444, comment="qwer" }

users
  { uid:12345, name:"john" }
  { uid:99999, name:"mia"  }

Есть ли способ вытащить все комментарии с определенным полем (например.... find ({pid: 444})) и пользовательскую информацию, связанную с каждым комментарием за один раз?

В настоящий момент я получаю комментарии, соответствующие моим критериям, а затем вычисляю все uid в этом наборе результатов, получая пользовательские объекты и объединяя их с результатами комментариев. Похоже, я делаю это неправильно.

  • 30
    Последний ответ на этот вопрос, вероятно, является наиболее актуальным, поскольку MongoDB 3.2+ реализовал решение для соединения под названием $ lookup. Думал, что я бы толкнул это здесь, потому что, возможно, не все будут читать до дна. stackoverflow.com/a/33511166/2593330
  • 6
    Правильно, $ lookup был введен в MongoDB 3.2. Подробности можно найти на docs.mongodb.org/master/reference/operator/aggregation/lookup/…
Показать ещё 1 комментарий
Теги:
join
normalization

19 ответов

244

Как и в случае с Mongo 3.2, ответы на этот вопрос в основном уже не верны. Новый оператор $lookup, добавленный в конвейер агрегации, по существу идентичен левому внешнему соединению:

https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup

Из документов:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

Конечно, Mongo не является реляционной базой данных, и разработчики стараются рекомендовать конкретные варианты использования для $lookup, но по крайней мере, начиная с 3.2, соединение теперь возможно с MongoDB.

  • 11
    является ли $ lookup по производительности лучшим вариантом?
  • 5
    Согласовано. Это лучший ответ .
Показать ещё 8 комментариев
128

Эта страница на официальном сайте mongodb адресует именно этот вопрос:

http://docs.mongodb.org/ecosystem/tutorial/model-data-for-ruby-on-rails/

Когда мы показываем наш список историй, нам нужно будет указать имя пользователя, разместившего историю. Если бы мы использовали реляционную базу данных, мы могли бы выполнить соединение с пользователями и магазинами и получить все наши объекты в одном запросе. Но MongoDB не поддерживает объединения, и поэтому время от времени требуется бит денормализации. Здесь это означает кэширование атрибута "имя пользователя".

Релятивные пуристы уже чувствуют себя неловко, как будто мы нарушаем какой-то универсальный закон. Но давайте иметь в виду, что коллекции MongoDB не эквивалентны реляционным таблицам; каждая из которых служит уникальной проектной цели. Нормализованная таблица обеспечивает атомный изолированный кусок данных. Однако документ более тесно представляет собой объект в целом. В случае сайта социальных новостей можно утверждать, что имя пользователя является неотъемлемой частью отправленной истории.

  • 115
    Тогда почему так много людей любят MongoDB. Я не понимаю: |
  • 48
    @dudelgrincen это смена парадигмы от нормализации и реляционных баз данных. Цель NoSQL - очень быстро читать и писать из базы данных. С BigData у вас будет множество приложений и серверов переднего плана с меньшим числом в БД. Вы должны делать миллионы транзакций в секунду. Выгрузите тяжелую работу из базы данных и перенесите ее на уровень приложения. Если вам нужен глубокий анализ, вы запускаете задание интеграции, которое помещает ваши данные в базу данных OLAP. В любом случае, вы не должны получать много глубоких запросов от ваших баз данных OLTP.
Показать ещё 11 комментариев
122

Мы можем объединить/объединить все данные внутри одной коллекции с простой функцией в нескольких строках с помощью клиентской консоли mongodb, и теперь мы сможем выполнить требуемый запрос. Ниже полный пример,

.- Авторы:

db.authors.insert([
    {
        _id: 'a1',
        name: { first: 'orlando', last: 'becerra' },
        age: 27
    },
    {
        _id: 'a2',
        name: { first: 'mayra', last: 'sanchez' },
        age: 21
    }
]);

.- Категории:

db.categories.insert([
    {
        _id: 'c1',
        name: 'sci-fi'
    },
    {
        _id: 'c2',
        name: 'romance'
    }
]);

.- Книги

db.books.insert([
    {
        _id: 'b1',
        name: 'Groovy Book',
        category: 'c1',
        authors: ['a1']
    },
    {
        _id: 'b2',
        name: 'Java Book',
        category: 'c2',
        authors: ['a1','a2']
    },
]);

.- Книжное кредитование

db.lendings.insert([
    {
        _id: 'l1',
        book: 'b1',
        date: new Date('01/01/11'),
        lendingBy: 'jose'
    },
    {
        _id: 'l2',
        book: 'b1',
        date: new Date('02/02/12'),
        lendingBy: 'maria'
    }
]);

.- Магия:

db.books.find().forEach(
    function (newBook) {
        newBook.category = db.categories.findOne( { "_id": newBook.category } );
        newBook.lendings = db.lendings.find( { "book": newBook._id  } ).toArray();
        newBook.authors = db.authors.find( { "_id": { $in: newBook.authors }  } ).toArray();
        db.booksReloaded.insert(newBook);
    }
);

.- Получить новые данные коллекции:

db.booksReloaded.find().pretty()

.- Ответ:)

{
    "_id" : "b1",
    "name" : "Groovy Book",
    "category" : {
        "_id" : "c1",
        "name" : "sci-fi"
    },
    "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        }
    ],
    "lendings" : [
        {
            "_id" : "l1",
            "book" : "b1",
            "date" : ISODate("2011-01-01T00:00:00Z"),
            "lendingBy" : "jose"
        },
        {
            "_id" : "l2",
            "book" : "b1",
            "date" : ISODate("2012-02-02T00:00:00Z"),
            "lendingBy" : "maria"
        }
    ]
}
{
    "_id" : "b2",
    "name" : "Java Book",
    "category" : {
        "_id" : "c2",
        "name" : "romance"
    },
    "authors" : [
        {
            "_id" : "a1",
            "name" : {
                "first" : "orlando",
                "last" : "becerra"
            },
            "age" : 27
        },
        {
            "_id" : "a2",
            "name" : {
                "first" : "mayra",
                "last" : "sanchez"
            },
            "age" : 21
        }
    ],
    "lendings" : [ ]
}

Я надеюсь, что эти строки помогут вам.

  • 2
    мне интересно, можно ли запустить этот же код с помощью доктрины mongodb?
  • 4
    Что происходит, когда один из ссылочных объектов получает обновление? Это обновление автоматически отражается в объекте книги? Или этот цикл нужно запустить снова?
Показать ещё 6 комментариев
34

Вы должны сделать это так, как вы описали. MongoDB является нереляционной базой данных и не поддерживает объединения.

  • 4
    Кажется неправильным в плане производительности, если исходить из опыта работы с сервером sql, но, возможно, не так уж и плохо с документом db?
  • 3
    Я также был бы рад, если MongoDB будет использовать набор результатов (с выбранными возвращаемыми полями) в качестве входных данных для нового запроса за один раз, во многом как вложенные запросы в SQL.
Показать ещё 2 комментария
17

Вот пример коллекций Актеры и Фильмы:

https://github.com/mongodb/cookbook/blob/master/content/patterns/pivot.txt

Использует метод .mapReduce()

* join - альтернатива объединению в документарно-ориентированные базы данных

  • 17
    -1, это НЕ объединяет данные из двух коллекций. Он использует данные из одной коллекции (актеров), которые вращают данные вокруг. Так что вещи, которые были ключами, теперь являются значениями, а значения теперь являются ключами ... сильно отличающимися от JOIN.
  • 12
    Это именно то, что вам нужно сделать, MongoDB не реляционная, а ориентированная на документы. MapReduce позволяет играть с данными с большой производительностью (вы можете использовать кластер и т. Д.), Но даже для простых случаев это очень полезно!
Показать ещё 1 комментарий
16

Как уже указывалось, вы пытаетесь создать реляционную базу данных из какой-либо реляционной базы данных, которую вы действительно не хотите делать, но в любом случае, если у вас есть случай, когда вы должны это сделать, это решение, которое вы можете использовать, Сначала мы делаем поиск foreach в коллекции A (или в вашем случае пользователей), и затем мы получаем каждый элемент как объект, тогда мы используем свойство объекта (в вашем случае uid) для поиска в нашей второй коллекции (в ваших комментариях к случаю), если мы может найти его, тогда у нас есть совпадение, и мы можем печатать или что-то делать с ним. Надеюсь, это поможет вам и удачи:)

db.users.find().forEach(
function (object) {
    var commonInBoth=db.comments.findOne({ "uid": object.uid} );
    if (commonInBoth != null) {
        printjson(commonInBoth) ;
        printjson(object) ;
    }else {
        // did not match so we don't care in this case
    }
});
  • 1
    Не вижу причин для того, чтобы за это проголосовали.
  • 0
    Разве это не найти предмет, на котором мы сейчас работаем?
Показать ещё 1 комментарий
10

Это зависит от того, что вы пытаетесь сделать.

В настоящее время он настроен как нормализованная база данных, и это нормально, и то, как вы это делаете, уместно.

Однако есть и другие способы сделать это.

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

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

С помощью NoSQL, если вы согласны с тем, что избыточность и пространство для хранения не являются проблемами из-за их стоимости (как в процессорное время, требуемое для обновления, так и для затрат на жесткий диск для хранения дополнительных данных), денормализация не является проблемой (для встроенных массивов, которые становятся сотнями тысяч элементов, это может быть проблемой производительности, но большую часть времени это не проблема). Кроме того, у вас будет несколько серверов приложений и интерфейсов для каждого кластера баз данных. Попросите их сделать тяжелый подъем соединений и позволить серверам баз данных придерживаться чтения и записи.

TL; DR: То, что вы делаете, прекрасно, и есть другие способы сделать это. Ознакомьтесь с образцами моделей данных документации mongodb для некоторых замечательных примеров. http://docs.mongodb.org/manual/data-modeling/

  • 7
    «Нормализация проистекает из концепции попыток сэкономить место». ИМХО нормализация исходит из концепции избежания избыточности. Скажем, вы храните имя пользователя вместе с постом в блоге. Что если она выйдет замуж? В ненормализованной модели вам придется просмотреть все сообщения и изменить название. В нормализованной модели вы обычно меняете ОДНУ запись.
  • 0
    @DanielKhan - предотвращение избыточности и экономия места - схожие концепции, но я согласен с тем, что при повторном анализе избыточность является основной причиной этого проекта. Я перефразирую Спасибо за примечание.
9

Существует спецификация, которая поддерживает множество драйверов, называемых DBRef.

DBRef - более формальная спецификация для создания ссылок между документами. DBRefs (обычно) включают имя коллекции, а также идентификатор объекта. Большинство разработчиков используют только DBRefs, если коллекция может измениться с одного документа на другой. Если ваша ссылочная коллекция всегда будет одинаковой, рекомендации по руководству, описанные выше, более эффективны.

Взято из MongoDB Документация: Модели данных > Ссылка на модель данных > Ссылки на базы данных

7

При правильной комбинации $lookup, $project и $соответствия вы можете присоединиться к нескольким таблицам по нескольким параметрам. Это связано с тем, что они могут быть связаны несколько раз.

Предположим, что мы хотим сделать следующее (ссылка)

SELECT S.* FROM LeftTable S
LEFT JOIN RightTable R ON S.ID =R.ID AND S.MID =R.MID WHERE R.TIM >0 AND 
S.MOB IS NOT NULL

Шаг 1: Свяжите все таблицы

вы можете $искать столько таблиц, сколько хотите.

$lookup - по одному для каждой таблицы в запросе

$unwind - потому что данные денормализированы правильно, иначе они завернуты в массивы

Код Python.

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"}

                        ])

Шаг 2: Определите все условные обозначения

$project: укажите здесь все условные операторы, а также все переменные, которые вы хотите выбрать.

Код Python..

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }}
                        ])

Шаг 3. Присоедините все условные обозначения

$match - присоединяться ко всем условиям, используя OR или AND и т.д. Их может быть несколько.

$project: undefine все условные обозначения

Код Python..

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "$R"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }},

                        # join all conditionals

                        {"$match": {
                          "$and": [
                            {"R.TIM": {"$gt": 0}}, 
                            {"MOB": {"$exists": True}},
                            {"midEq": {"$eq": True}}
                        ]}},

                        # undefine conditionals

                        {"$project": {
                          "midEq": 0
                        }}

                        ])

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

7

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

db.comments.aggregate({
    $lookup:{
        from:"users",
        localField:"uid",
        foreignField:"uid",
        as:"users_comments"
    }
})

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

db.users.aggregate({
    $lookup:{
        from:"comments",
        localField:"uid",
        foreignField:"uid",
        as:"users_comments"
    }
})

Он будет работать так же, как левое и правое соединение в SQL.

5

До 3.2.6, Mongodb не поддерживает запрос соединения как mysql. ниже решения, которое работает для вас.

 db.getCollection('comments').aggregate([
        {$match : {pid : 444}},
        {$lookup: {from: "users",localField: "uid",foreignField: "uid",as: "userData"}},
   ])
3

$ lookup (агрегация)

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

Матч по равенству

Чтобы выполнить совпадение равенства между полем из входных документов с полем из документов "объединенной" коллекции, этап $ lookup имеет следующий синтаксис:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

Операция будет соответствовать следующему выражению псевдо-SQL:

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT <documents as determined from the pipeline>
                               FROM <collection to join>
                               WHERE <pipeline> );

URL Mongo

3

Вы можете запускать SQL-запросы, включая объединение в MongoDB с mongo_fdw из Postgres.

2

MongoDB не разрешает объединения, но вы можете использовать плагины для его обработки. Проверьте плагин mongo-join. Это лучшее, и я уже использовал его. Вы можете установить его с помощью npm прямо следующим образом npm install mongo-join. Вы можете просмотреть полную документацию с примерами.

(++) действительно полезный инструмент, когда нам нужно объединить (N) коллекции

(-) мы можем применять условия только на верхнем уровне запроса

Пример

var Join = require('mongo-join').Join, mongodb = require('mongodb'), Db = mongodb.Db, Server = mongodb.Server;
db.open(function (err, Database) {
    Database.collection('Appoint', function (err, Appoints) {

        /* we can put conditions just on the top level */
        Appoints.find({_id_Doctor: id_doctor ,full_date :{ $gte: start_date },
            full_date :{ $lte: end_date }}, function (err, cursor) {
            var join = new Join(Database).on({
                field: '_id_Doctor', // <- field in Appoints document
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            }).on({
                field: '_id_Patient', // <- field in Appoints doc
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            })
            join.toArray(cursor, function (err, joinedDocs) {

                /* do what ever you want here */
                /* you can fetch the table and apply your own conditions */
                .....
                .....
                .....


                resp.status(200);
                resp.json({
                    "status": 200,
                    "message": "success",
                    "Appoints_Range": joinedDocs,


                });
                return resp;


            });

    });
  • 0
    Не вижу причин для того, чтобы за это проголосовали.
  • 0
    На самом деле я проголосовал за это решение
0

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

Вы можете использовать mongo-join-query, чтобы автоматически создать конвейер агрегации из вашего запроса.

Вот как выглядит ваш запрос:

const mongoose = require("mongoose");
const joinQuery = require("mongo-join-query");

joinQuery(
    mongoose.models.Comment,
    {
        find: { pid:444 },
        populate: ["uid"]
    },
    (err, res) => (err ? console.log("Error:", err) : console.log("Success:", res.results))
);

В результате результат будет иметь пользовательский объект в поле uid, и вы можете связать столько уровней, сколько захотите. Вы можете заполнить ссылку на пользователя, что делает ссылку на команду, которая ссылается на что-то еще и т.д.

Отказ от ответственности: я написал mongo-join-query для решения этой точной проблемы.

0

playORM может сделать это для вас, используя S-SQL (масштабируемый SQL), который просто добавляет разделение, так что вы можете делать объединения внутри разделов.

-3

Я думаю, если вам нужны нормализованные таблицы данных - вам нужно попробовать другие решения для баз данных.

Но я нашел, что решение для MOngo на Git Кстати, во вставке кода - у него есть название фильма, , но noi movie ID.

Проблема

У вас есть коллекция Актеров с множеством фильмов, которые они сделали.

Вы хотите создать коллекцию фильмов с массивом Актеров в каждом.

Некоторые примеры данных

 db.actors.insert( { actor: "Richard Gere", movies: ['Pretty Woman', 'Runaway Bride', 'Chicago'] });
 db.actors.insert( { actor: "Julia Roberts", movies: ['Pretty Woman', 'Runaway Bride', 'Erin Brockovich'] });

Решение

Нам нужно перебирать каждый фильм в документе Actor и выделять каждый фильм по отдельности.

Ловушка здесь находится в фазе уменьшения. Мы не можем испускать массив из фазы уменьшения, поэтому мы должны построить массив Actors внутри возвращаемого документа "value".

Код
map = function() {
  for(var i in this.movies){
    key = { movie: this.movies[i] };
    value = { actors: [ this.actor ] };
    emit(key, value);
  }
}

reduce = function(key, values) {
  actor_list = { actors: [] };
  for(var i in values) {
    actor_list.actors = values[i].actors.concat(actor_list.actors);
  }
  return actor_list;
}

Обратите внимание, что actor_list - это фактически объект javascript, содержащий массив. Также обратите внимание, что карта излучает ту же структуру.

Запустите следующую команду, чтобы выполнить отображение/сокращение, вывести ее в коллекцию "pivot" и распечатать результат:

printjson (db.actors.mapReduce(map, reduce, "pivot" )); db.pivot.find() Foreach (printjson);.

Вот пример вывода, обратите внимание, что "Pretty Woman" и "Runaway Bride" имеют как "Richard Gere", так и "Julia Roberts".

{ "_id" : { "movie" : "Chicago" }, "value" : { "actors" : [ "Richard Gere" ] } }
{ "_id" : { "movie" : "Erin Brockovich" }, "value" : { "actors" : [ "Julia Roberts" ] } }
{ "_id" : { "movie" : "Pretty Woman" }, "value" : { "actors" : [ "Richard Gere", "Julia Roberts" ] } }
{ "_id" : { "movie" : "Runaway Bride" }, "value" : { "actors" : [ "Richard Gere", "Julia Roberts" ] } }

  • 0
    Обратите внимание, что большая часть содержания этого ответа (то есть бит на понятном английском языке) скопирована из поваренной книги MongoDB на GitHub-ссылке, предоставленной ответчиком.
-4

Нет, похоже, что вы делаете это неправильно. Соединения MongoDB являются "клиентской стороной". В значительной степени, как вы сказали:

В настоящий момент я получаю комментарии, соответствующие моим критериям, а затем вычисляю все uid в этом наборе результатов, получая пользовательские объекты и объединяя их с результатами комментариев. Похоже, я делаю это неправильно.

1) Select from the collection you're interested in.
2) From that collection pull out ID you need
3) Select from other collections
4) Decorate your original results.

Это не "реальное" соединение, но оно на самом деле намного полезнее, чем соединение SQL, потому что вам не нужно иметь дело с повторяющимися строками для "многих" сторонних объединений, вместо этого вы украшаете первоначально выбранный набор.

На этой странице много глупостей и FUD. Оказывается, 5 лет спустя MongoDB все еще есть.

  • 0
    «вам не нужно иметь дело с дублирующимися строками для« многих »двусторонних объединений» - понятия не имеете, что вы подразумеваете под этим. Вы можете уточнить?
  • 0
    Даунвот, правда?
Показать ещё 1 комментарий
-5

Мы можем объединить две коллекции, используя sub-запрос mongoDB. Вот пример, Commentss -

`db.commentss.insert([
  { uid:12345, pid:444, comment:"blah" },
  { uid:12345, pid:888, comment:"asdf" },
  { uid:99999, pid:444, comment:"qwer" }])`

Userss -

db.userss.insert([
  { uid:12345, name:"john" },
  { uid:99999, name:"mia"  }])

Суб-запрос MongoDB для JOIN -

`db.commentss.find().forEach(
    function (newComments) {
        newComments.userss = db.userss.find( { "uid": newComments.uid } ).toArray();
        db.newCommentUsers.insert(newComments);
    }
);`

Получить результат из недавно созданной коллекции -

db.newCommentUsers.find().pretty()

Результат -

`{
    "_id" : ObjectId("5511236e29709afa03f226ef"),
    "uid" : 12345,
    "pid" : 444,
    "comment" : "blah",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f2"),
            "uid" : 12345,
            "name" : "john"
        }
    ]
}
{
    "_id" : ObjectId("5511236e29709afa03f226f0"),
    "uid" : 12345,
    "pid" : 888,
    "comment" : "asdf",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f2"),
            "uid" : 12345,
            "name" : "john"
        }
    ]
}
{
    "_id" : ObjectId("5511236e29709afa03f226f1"),
    "uid" : 99999,
    "pid" : 444,
    "comment" : "qwer",
    "userss" : [
        {
            "_id" : ObjectId("5511238129709afa03f226f3"),
            "uid" : 99999,
            "name" : "mia"
        }
    ]
}`

Надеюсь, что это поможет.

  • 7
    Почему вы в основном скопировали этот почти идентичный годичный ответ? stackoverflow.com/a/22739813/4186945

Ещё вопросы

Сообщество Overcoder
Наверх
Меню