574 votes

Comment puis-je effectuer la jointure SQL équivalent à MongoDB ?

Comment dois-je effectuer la Jointure SQL équivalent dans MongoDB?

Par exemple, dire que vous avez deux collections (les utilisateurs et les commentaires) et je tiens à tirer tous les commentaires avec pid=444 avec les infos de l'utilisateur pour chaque.

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"  }

Est-il un moyen pour tirer tous les commentaires avec un certain domaine (par exemple. ...find({pid:444}) ) et l'utilisateur des informations associées à chaque commentaire d'un seul coup?

Pour le moment, je suis le premier à obtenir les commentaires qui correspondent à mes critères, puis de déterminer toutes les uid de l'ensemble des résultats, l'obtention de l'utilisateur des objets, et de les fusionner avec le commentaire des résultats. On dirait que je suis de faire le mal.

155voto

Orlando Becerra Points 71

Nous pouvons fusionner ou joindre toutes les données à l'intérieur d'une seule collection avec une simple fonction dans quelques lignes à l'aide de la mongodb client de la console, et maintenant, nous pourrions être en mesure d'effectuer la requête souhaitée. Ci-dessous un exemple complet,

.- Auteurs:

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

.- Catégories:

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

.- Livres

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

.- Prêt de livres

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'
    }
]);

.- La magie:

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

.- Obtenir la nouvelle collection de données:

db.booksReloaded.find().pretty()

.- Réponse :)

{
    "_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" : [ ]
}

J'espère que ces lignes peuvent vous aider.

151voto

William Stein Points 1107

Cette page sur le site officiel de mongodb adresses de site exactement à cette question:

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

"Quand on affiche la liste de nos histoires, nous allons avoir besoin d'afficher le nom de l'utilisateur qui a posté l'histoire. Si nous étions à l'aide d'une base de données relationnelle, nous pourrions effectuer une jointure sur les utilisateurs et les magasins, et bénéficiez de tous nos objets en une seule requête. Mais MongoDB ne prend pas en charge les jointures et, ainsi, à la fois, nécessite peu de dénormalisation. Ici, cela signifie la mise en cache le 'nom d'utilisateur' attribut. [...] Relationnelles, les puristes peuvent se sentir mal à l'aise, comme si nous étions une violation de certains de loi universelle. [...]"

38voto

Otto Allmendinger Points 11853

Vous devez faire de la manière que vous avez décrit. MongoDB est une base de données non relationnelles et ne supporte pas les jointures.

17voto

antitoxic Points 1804

Voici un exemple d’un « join » * collections acteurs et films :

http://Cookbook.MongoDB.org/patterns/pivot/

Il fait appel à `` méthode

* join - une alternative à la rejoindre dans les bases de données orientées document

11voto

Pickels Points 9201

Il y a un cahier des charges que beaucoup de pilotes de soutien, appelé DBRef.

DBRef est un plus de spécification formelle pour la création de références entre les documents. DBRefs (en général), inclure un nom de collection, ainsi qu'une oject id. La plupart des développeurs utilisent uniquement DBRefs si la collection pouvez modifier à partir d'un document à l'autre. Si votre référencé collection sera toujours le même, le manuel, les références énumérées ci-dessus sont plus efficaces.

Source

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X