10
votes

Sélection de chaque nième élément d'une grande collection MongoDB avec PHP?

J'ai une collection MongoDB avec des éléments ~ 4M.

Je veux saisir x nombre de ces éléments, uniformément espacés par toute la collection.

E.g., Obtenez 1000 éléments de la collection - une des 4000 lignes.

En ce moment, je reçois toute la collection dans un curseur, puis n'écrivez que chaque nième élément. Cela me donne ce dont j'ai besoin, mais la charge originale de l'énorme collection prend beaucoup de temps.

Y a-t-il un moyen facile de faire cela? À l'heure actuelle, mon approche supposée est de faire une requête JS sur une propriété Index incrémentée, avec un module de module. Une implémentation de PHP de cette:

db.collection.find ({i: {$ mod: [10000,0]}})

Mais cela semble être probablement prendre autant de temps pour que la requête soit courante.

Jer


1 commentaires

Avez-vous trouvé une solution?


6 Réponses :


0
votes

Je pense que le problème principal est que la collection peut être distribuée sur des serveurs et que vous devez ainsi faire itérair sur toute la collection.


1 commentaires

Dans ce cas, je cours tout sur un serveur local.



0
votes

Ne pas mettre l'ensemble du jeu de données dans un curseur. Étant donné que la commande de lignes n'est pas importante, il suffit de collecter x des lignes aléatoires hors de votre total, renvoyer cela en conséquence, puis modifier ces enregistrements


4 commentaires

Le problème est que j'ai besoin d'éléments répartis uniformément de ma collection - c'est-à-dire tous les 1000ème élément.


Créez un champ de comptage, puis utilisez la carte pour filtrer chaque nième élément, puis réduire pour fonctionner sur cet enregistrement.


Merci ... va essayer cela. J'ai déjà un champ de compte en place. Il suffit de vouloir essayer de faire des têtes / queues de la carte réduire la documentation.


Aucun progrès? S'il vous plaît votez ma réponse si cela vous a aidé et postez votre solution afin que d'autres personnes puissent apprendre!



0
votes

personnellement, je concevrais dans une valeur "modulus", le peuplerait avec quelque chose qui est une fonction représentative des données - donc si vos données ont été insérées à intervalles réguliers tout au long de la journée, vous pourriez faire un module de temps, s'il y a rien de prévisible alors vous pouvez utiliser une valeur aléatoire; Avec une collection de cette taille, elle aurait tendance à une distribution même assez rapidement.

Un exemple en utilisant une valeur aléatoire ... xxx


0 commentaires

-6
votes

Si seulement vos données étaient dans une base de données SQL, comme cela devrait être, ... Cette question ne serait pas dans PHP et la réponse serait si facile et rapide ...

Chargement de quelque chose dans un curseur au lieu de calculer les informations directement dans la DB est définitivement une mauvaise idée, n'est-il pas possible de le faire directement dans le truc de Mongodb?


4 commentaires

Cette réponse est si en arrière


Lors de la manipulation de seulement 4 millions d'éléments et de faire des opérations qui ne sont pas originaires de MongoDB, vous devriez utiliser PostgreSQL.


Pourquoi? Pourquoi PostgreSQL serait-il meilleur ici? Je suis un utilisateur lourd de bases de données SQL, mais ce type de requête est mauvais pour la plupart des bases de données. De plus, "Thingy Mongodb"? Ne semble pas que vous sachiez vraiment ce que vous parlez de MongoDB à faire autorité ici. Pas même sûr de ce que vous entendez par la deuxième partie de votre réponse.


Cette requête convient parfaitement à toutes les bonnes RDBM (PGSQL, Oracle, MSSQL).



0
votes

Un moyen simple (inefficace) de faire cela est avec un flux.

var stream = collection.find({}).stream();
var counter = 0;

stream.on("data", function (document) {
  counter++;

  if (counter % 10000 == 0) {
    console.log(JSON.stringify(document, null, 2));
    //do something every 10,000th time
  }
});


0 commentaires

1
votes

Utilisez $ échantillon .

Ceci renvoie un échantillon aléatoire qui est à peu près "chaque nième document".

Recevoir exactement chaque nième document d'un ensemble de résultats, vous devrez fournir un ordre de tri et itérer l'ensemble du résultat défini en supprimant tous les documents non désirés dans votre application.


0 commentaires