web-dev-qa-db-fra.com

Incrémentation automatique dans MongoDB pour stocker la séquence d'ID utilisateur unique

Je suis en train de créer un système d’analyse, l’appel d’API fournirait un ID utilisateur unique, mais ce n’est pas en séquence et trop rare.

Je dois attribuer à chaque ID utilisateur unique un identifiant d'incrémentation automatique pour marquer un point de données d'analyse dans un bitarray/bitet. Ainsi, les rencontres rencontrées par le premier utilisateur correspondraient au premier bit de la matrice de bits, le deuxième utilisateur serait le deuxième bit de la matrice de bits, etc.

Existe-t-il donc un moyen solide et rapide de générer des ID utilisateur uniques incrémentiels dans MongoDB?

17
est

Vous pouvez, mais vous ne devriez pas https://web.archive.org/web/20151009224806/http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

Chaque objet de mongo a déjà un identifiant et peut être trié par ordre d'insertion. Qu'y a-t-il de mal à obtenir une collection d'objets utilisateur, à l'itérer et à l'utiliser comme ID incrémenté? Er aller pour le type de travail de carte-réduire entièrement

11

Selon la réponse choisie, vous pouvez utiliser findAndModify pour générer des ID séquentiels.

Mais je suis fermement en désaccord avec l'opinion selon laquelle vous ne devriez pas faire cela. Tout dépend des besoins de votre entreprise. Avoir un identifiant 12 octets peut être très consommateur de ressources et causer de gros problèmes d’évolutivité dans le futur.

J'ai détaillé réponse ici .

16
expert

Commencez par créer une collection counters , qui gardera trace de la dernière valeur de séquence pour tous les champs de séquence.

        db.createCollection("counters")

Utilisez le code suivant pour insérer ce document de séquence dans la collection de compteurs -

    db.counters.insert({_id:"tid",sequence_value:0})

Créer une fonction Javascript:

    function getNextSequenceValue(sequenceName){
        var sequenceDocument = db.counters.findAndModify({
        query:{_id: sequenceName },
        update: {$inc:{sequence_value:1}},
        new:true
          });
      return sequenceDocument.sequence_value;
      }

Insérer deux documents:

            db.products.insert({
           "_id":getNextSequenceValue("tid"),
           "product":"Samsung",
           "category":"mobiles"
             })


           db.products.insert({
            "_id":getNextSequenceValue("tid"),
            "product":"Samsung S3",
            "category":"mobiles"
              })

Obtenir les documents insérés:

            db.prodcuts.find()

SORTIE

{"_id": 1, "produit": "Samsung", "catégorie": "mobiles"}

{"_id": 2, "produit": "Samsung S3", "catégorie": "mobiles"}

13
Rizwan Siddiquee

Je sais que c'est une vieille question, mais je posterai ma réponse pour la postérité ... 

Cela dépend du système que vous construisez et des règles commerciales en vigueur.

Je construis un CRM modéré à large en MongoDb, C # (API Backend) et Angular (application Web Frontend) et trouve ObjectId tout à fait terrible pour une utilisation dans Angular Routing pour sélectionner des entités particulières. Même chose avec le routage du contrôleur API.

La suggestion ci-dessus a parfaitement fonctionné pour mon projet.

db.contacts.insert({
 "id":db.contacts.find().Count()+1,
 "name":"John Doe",
 "emails":[
    "[email protected]",
    "[email protected]"
 ],
 "phone":"555111322",
 "status":"Active"
});

La raison pour laquelle il est parfait pour mon cas, mais pas dans tous les cas, est que, comme le dit le commentaire ci-dessus, si vous supprimez 3 enregistrements de la collection, vous obtiendrez des collisions. 

Mes règles d'entreprise stipulent qu'en raison de nos SLA internes, nous ne sommes pas autorisés à supprimer les données de correspondance ou les enregistrements de clients plus longtemps que la durée de vie potentielle de l'application que j'écris. Par conséquent, je marque simplement les enregistrements avec un "Statut" enum qui est soit "actif" ou "supprimé". Vous pouvez supprimer quelque chose de l'interface utilisateur, et le message "Le contact a été supprimé" ne change que si le statut du contact est "Supprimé" et lorsque l'application appelle le référentiel pour obtenir une liste de contacts, je filtre supprimer les enregistrements supprimés avant d'envoyer les données à l'application cliente. 

Par conséquent, db.collection.find (). Count () + 1 est une solution parfaite pour moi ... 

Cela ne fonctionnera pas pour tout le monde, mais si vous ne supprimez pas de données, cela fonctionne bien.

7
Alex Nicholas

Premier enregistrement devrait être ajouter 

"_id" = 1    in your db

$database = "demo";
$collections ="democollaction";
echo getnextid($database,$collections);

function getnextid($database,$collections){

     $m = new MongoClient();
    $db = $m->selectDB($database);
    $cursor = $collection->find()->sort(array("_id" => -1))->limit(1);
    $array = iterator_to_array($cursor);

    foreach($array as $value){



        return $value["_id"] + 1;

    }
 }
0
Darshan Vithani