2017-03-11 4 views
1

Ich verstehe die Frage ist ein bisschen verwirrend. Bär mit mir,MongoDB, Array-Feld von Objekten mit inkrementeller Eigenschaft

Nehmen wir an, ich habe ein Class-Dokument, das Student-Eigenschaft als Array enthält. Jetzt sollten diese Studenten eine inkrementelle Id haben, aber ich bin mir nicht sicher, wie das zu tun ist, wenn gleichzeitig Einfügungen Abfragen an das Dokument senden.

Beispiel:

sagen wir mal Klasse mein Dokument in db ist.

var class = { 
    'students':[{ 
     'name': 'Bob' 
     'id' :1 
    }] 
} 

jetzt, wenn ich Einsatz am der Student Sally ({'name': 'Sally'}) zu class.students schieben würde ich sie mag 2 wie id zu erhalten.

Ich könnte abfragen, um die neueste ID in der db zu bekommen und diese um eins zu erhöhen und sie als Sallys ID zu verwenden.

Allerdings weiß ich nicht, was passiert, wenn zwei verschiedene Anfragen gleichzeitig gemacht wurden und einer von ihnen versucht, einfügen Push Sally und der andere Jack. Wie kann ich sicherstellen, dass Sally und Jack nicht dieselbe ID bekommen?

Eine Anmerkung; Ich möchte mich nicht auf den Array-Index für das ID-Feld verlassen.

+0

Verwenden Sie eine GUID oder UUID, die bei jeder Erstellung am wahrscheinlichsten eindeutig ist. – Karthik

+0

Richtig, aber ich möchte auch, dass die ID lesbar ist. Ich möchte Bob als "Student-1" und nicht als "Student-asfasf29-dajs-doajsdo2ke-12" bezeichnen. – Hasan

Antwort

1

Sie können dies mit Hilfe der Zählersammlung

1.Insert in die Zähler Sammlung der Anfangswert für die StudentID:

db.counters.insert(
    { 
     _id: "studentId", 
     seq: 0 
    } 
) 

2. eine getNextSequence Funktion erstellen, die einen Namen akzeptiert die Sequenz. Die Funktion verwendet die findAndModify() -Methode atomar den seq Wert erhöhen und das Rück diesen neuen Wert

function getNextSequence(name) { 
    var ret = db.counters.findAndModify(
      { 
      query: { _id: name }, 
      update: { $inc: { seq: 1 } }, 
      new: true 
      } 
    ); 

    return ret.seq; 
} 

Als findAndModify atomare Operation ist, getNextSequence() wird immer nächsten Wert, auch bei den gleichzeitigen Anforderungen zurückgeben .

3.Use diese getNextSequence() Funktion beim Insert/Push

//let's assume you already have a 'student' variable that represents a student doc 
student['id'] = getNextSequence("studentId"); 
db.classes.update(
    { _id: 1 }, 
    { $addToSet: { students: student } } 
) 

Mehr Details über ein automatisch inkrementierende Sequenzfeld könnte in den corresponding tutorial auf MongoDB Website.

Verwandte Themen