2011-01-26 8 views
2

Dans une application sur laquelle je travaille, une exigence consiste à effectuer une intersection massive, à hauteur de 10 à 1 000 000 articles environ. Les éléments que nous croisons sont simplement ObjectId. Par exemple, il y a un document de boîtes et dans le document des boîtes il y a un item_ids Array. Ce tableau item_ids pour chaque boîte contient 10-1 000 000 ObjectId.intersection de l'ensemble de serveurs côté mongodb

L'objectif final ici est de dire, donné la case A avec ObjectId 4d3dc3898951498107000005, et la case B avec ObjectId 4d3dc3898951498107000002, quels item_id ont-ils en commun?

Voici comment im faire:

db.boxes.distinct("item_ids", {'_id' : {$in : [ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}) 

Tout d'abord curieux si cela semble être une approche saine d'esprit. Dans ma recherche jusqu'à présent, il semble que la réduction de carte est une suggestion courante pour les grandes intersections, mais qu'elle n'est pas recommandée pour les requêtes en temps réel.

Deuxièmement, curieux de savoir comment cela se comporterait dans un environnement fragmenté? Est-ce que mongos exécutera une partie de la requête sur le mongod et devra agréger mon résultat comme par magie?

Enfin, si ce qui précède est sain d'esprit, est-il aussi sain d'esprit à faire:

db.items.find({'_id' : { $in : db.eval(function() {return db.boxes.distinct("item_ids", {_id:{$in:[ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}); }) }}) 

Ce qui serait essentiellement trouvent les éléments à la fois la case A et la boîte B ont en commun, puis les matérialisant dans tous les objets dans une requête côté serveur. Cela semble également fonctionner avec .limit et .skip pour implémenter efficacement une pagination de l'ensemble de données.

De toute façon, tout commentaire est précieux, merci!

+0

Comment «distinct» va-t-il trouver des valeurs communes? Il "renvoie une liste de valeurs distinctes pour la clé donnée à travers une collection". Distinct n'a pas de fonction 'intersection', il vous donnera une liste de tous les Ids qui sont en A ou B. Ou voulez-vous dire 'union'? –

+0

Oy, oui, vous avez raison. J'ai clairement besoin de plus de café. Je suppose que je devrais supprimer cette question. Je vais laisser un peu en place au cas où il y aurait d'autres idées pour l'intersection tableau/ensemble côté serveur. Merci! – spotman

Répondre

3

Je pense que vous voudrez peut-être reconsidérer votre schéma. Si vous avez 1 000 000 ObjectID dans un tableau à 12 octets, chacun de 12 Mo ne compte même pas le surcoût BSON qui peut être significatif pour les grandes baies * (probablement 8 Mo de plus). Dans 1.8, nous élevons la taille maximale du document de 4 Mo à 16 Mo, mais même cela ne suffira pas pour les objets que vous cherchez à stocker. * Pour des raisons historiques, nous stockons l'index stingifié pour chaque élément dans le tableau, ce qui est bien quand vous avez < 100 éléments, mais additionne quand vous avez besoin de 6 ou 7 chiffres.

+0

ouais, je pense que tu as raison. Des idées d'un schéma qui pourrait mieux fonctionner, avec les caractéristiques de mongo? Je suis un peu nouveau pour mongo et n'ai rien de grand en production pour le moment. Une approche que j'ai considérée était possiblement avoir un document qui décrit quel élément va dans quelle boîte, IE box_items ou quelque chose. Mais cela commence à se sentir comme un rdbms et créerait des tonnes de documents minuscules. Mais Item et Box sont tous deux des classes de première classe dans cette application, et tous deux tirent un énorme avantage de la flexibilité du schéma de mongo. l'utilisation d'un rdbms donne l'impression de revenir en arrière :( – spotman

+0

Il est difficile de donner des conseils sur le schéma sans en savoir plus sur votre application. Je vous suggère d'envoyer un e-mail à la liste de diffusion mongodb: [email protected] – mstearn