2016-04-19 14 views
2

Ich arbeite mit Golong und MongoDB. Ich habe eine Sammlung, die ein Dokument aufbewahren muss, das beständig oder volatil sein kann. Wenn daher ein Ablaufdatum festgelegt wird (wie im Beispiel expireAt), wird das Dokument als flüchtig betrachtet und gelöscht, andernfalls wird es in der Sammlung aufbewahrt, es sei denn, es wird manuell gelöscht.MGO TTL indiziert Erstellung, um selektiv Dokumente zu löschen

Lesen this doc Ich habe einen Index gefunden, der funktionieren könnte, wie ich es brauche.

Grundsätzlich brauche ich diese Art von Index in mgo zu replizieren:

db.log_events.createIndex({ "expireAt": 1 }, { expireAfterSeconds: 0 }) 

db.log_events.insert({ 
    "expireAt": new Date('July 22, 2013 14:00:00'), 
    "logEvent": 2, 
    "logMessage": "Success!" 
}) 

ich gelesen habe (ich bin zurück für die Quelle dieser Informationen suchen), dass, wenn die expireAt ist kein gültiges Datum der Löschen wird nicht ausgelöst. Also denke ich, dass ich das expireDate nur auf ein gültiges Datum setzen muss, wenn ich es brauche, sonst überlasse ich es dem Go time.Time Nullwert.

Das ist mein Code-Basis

type Filter struct { 
    Timestamp time.Time  `bson:"createdAt"` 
    ExpireAt time.Time  `bson:"expireAt"` 
    Body  string  `bson:"body"` 
} 

// Create filter from data received via REST API. 
var filter Filter 
timestamp := time.Now() 

if theUserAction == "share" { // This is action will set the document as volatile 
    filter.ExpireAt = time.Now().Add(24 * time.Hour * 14) 
} 

filter.Timestamp = timestamp 
filter.Body = "A BODY" 

// Store filter in database 
session, err := mdb.GetMgoSession() // This is a wrapping method that returns a valid mgo session 
if err != nil { 
    return NewErrorInternal("Error connecting to database", err) 
} 
defer session.Close() 


// Get db with global data for legent 
collection := session.DB(database).C(filtersCollection) 

Meine Frage ist: Wie kann ich den Index so eingestellt, dass sie das Dokument löschen werde IF die expireAt Schlüssel gültig ist? Lesen der mgo documentation about Index Type es scheint nicht, wie es eine Möglichkeit, die zuvor angegeben Index nachzubilden, da nur die Bibliothek, das Feld ExpireAfter bietet ..

Auch ist es gültig ist anzunehmen, dass ein zerovalue von mongodb als interpretiert werden könnte ungültiges Datum?

Aus dem docs es January 1, year 1, 00:00:00.000000000 UTC ist, die wie ein gültiges Datum scheint tatsächlich ..

Was ich so etwas wie dies zu tun weit gedacht habe:

filtIdx := mgo.Index{ 
    Key:  []string{"expireAt"}, 
    Unique:  false, 
    Background: true, 
    Sparse:  false, 
    ExpireAfter: 0, 
} 
+0

Ich könnte falsch liegen, aber von der Spitze meines Kopfes Ich denke, die 'expireAfterSeconds: 0' würde tatsächlich mit einem '0' Wert sowieso ignoriert werden, da ich glaube, es muss ein positiver Wert sein. TTL-Bereinigungsprozesse laufen sowieso nur jede Minute, so dass jeder Ablauf von weniger als 60 Sekunden mindestens eine Minute länger dauert. Was den Rest betrifft, sage ich nicht, dass Sie das nicht können, aber Sie sollten vielleicht den Nutzen eines Index in Ihrem Go-Code überdenken. Indizes müssen nur einmal definiert werden und sind daher am besten in "Bereitstellungsskripten" implementiert, anstatt Teil des allgemeinen Codes zu sein. –

+0

Das doc selbst gibt an, dass 'expireAfterSeconds: 0' verwendet werden soll, wenn der Index an einem anderen Datumsschlüssel ablaufen soll. Wofür der Index erstellt wird, yeah, Sie haben Recht, das ist gerade in einem Deployment-Skript. – FredMaggiowski

+0

Warum denken Sie, dass Sie mir etwas über die Dokumentation mitteilen? Das ist nicht, was es überhaupt sagt und der "einzige" Schlüssel, den Sie verwenden können, sind die "singulären" Daten, die im Index angegeben sind. Und genau das sagt die Dokumentation. Ehrlich gesagt, gibt es zu jedem einzelnen Kommentar Links zu Benutzerprofilen. Wenn Sie einen Moment verbringen, um zu schauen, dann verstehen Sie vielleicht, dass die Person, die Sie informieren möchten, ein viel besseres Konzept als Sie selbst hat und daher "einen guten Rat gab". –

Antwort

2

Wie ich das einstellen kann Index also, dass es das Dokument löscht, wenn der expireAt Schlüssel gültig ist?

Ein Beispiel eines TTL-Index einzustellen Verwendung mgo.v2 wie unten ist:

index := mgo.Index{ 
    Key:   []string{"expireAt"}, 
    ExpireAfter: time.Second * 120, 
} 
err = coll.EnsureIndex(index) 

Wo das obige Beispiel wird bis 120 Sekunden der Exspiration. Siehe auch Expire Data from Collections by Setting TTL.

Ist es immer noch möglich, dass einige Dokumente überhaupt nicht ablaufen? Da dies das Verhalten freue ich mich, eine Sammlung zu erhalten, in dem einige Dokumente ablaufen kann, während andere

hartnäckig bleiben Sie omitempty Flag für ExpireAt struct Feld angeben, wie unten:

type Filter struct { 
    Timestamp time.Time `bson:"createdAt"` 
    Body  string `bson:"body"` 
    ExpireAt time.Time `bson:"expireAt,omitempty"` 
} 

, die im Wesentlichen Fügen Sie das Feld nur ein, wenn es nicht auf Null gesetzt ist. Weitere Informationen mgo.v2 bson.Marshal

Jetzt können Sie beispielsweise zwei Dokumente einfügen, von denen eines abläuft und das andere weiterhin besteht.Code-Beispiel:

var foo Filter 
foo.Timestamp = timestamp 
foo.Body = "Will be deleted per TTL index" 
foo.ExpireAt = time.Now() 
collection.Insert(foo) 

var bar Filter 
bar.Timestamp = timestamp 
bar.Body = "Persists until expireAt value is set" 
collection.Insert(bar) 

Später können Sie die expireAt Feld mit einem Update() als Beispiel gesetzt:

newValue := bson.M{"$set": bson.M{"expireAt": time.Now()}} 
err = collection.Update(queryFilter, newValue) 

einen gültigen Zeitwert für expireAt Feld einstellen, wäre es für die TTL machen qualifizieren Index. d.h. nicht mehr bestehen.

Abhängig von Ihrem Anwendungsfall, alternativ können Sie auch Remove() das Dokument anstelle von TTL-Index aktualisieren und sich darauf verlassen.

+0

Vielen Dank @Wan für die Antwort, es dauerte mehr als ein Jahr seit ich dieses Problem hatte, so jetzt kann ich nicht Testen Sie es, um die Lösung zu überprüfen; trotzdem scheint es der perfekte zu sein. Ich habe nicht über das Gob 'omitemperty' Schlüsselwort nachgedacht. Die Sache ist, dass es das Einfügen der 0-bewerteten Zeit vermeidet, was zur "Deaktivierung" des Index für dieses Dokument führt. Habe ich es richtig verstanden? Für jetzt bin ich upvoting die Antwort, ich werde es so schnell wie möglich testen, um es zu akzeptieren! :) – FredMaggiowski