Создание индексов MgO TTL для выборочного удаления документов


Я работаю с Голангом и Монгодбом. У меня есть коллекция, которая должна хранить документ, который может быть постоянным или изменчивым. Следовательно, если установлен срок годности (как в Примере expireAt), документ считается изменчивым и удаляется, иначе он будет храниться в коллекции, если только он не будет удален вручную.

Читаяэтот документ , я нашел индекс, который может работать так, как мне нужно.

В основном мне нужно скопировать этот тип индекса в mgo:

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!"
} )

Я прочитал (я ищу источник этой информации), что если expireAt не является действительной датой, удаление не будет триггером. Таким образом, я думаю, что все, что мне нужно сделать, это установить expireDate на действительную дату, когда мне это нужно, иначе я оставлю его в Go time.Time нулевое значение.

Это моя кодовая база

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)

Мой вопрос: как я могу установить индекс таким образом, что он удалит документ, если ключ expireAt действителен? Чтение документации mgo о Тип индекса похоже, что нет способа реплицировать ранее указанный индекс, так как библиотека предоставляет только поле ExpireAfter..

Кроме того, допустимо предположить, что нулевое значение может быть интерпретировано mongodb как недопустимая дата?

Из документов это January 1, year 1, 00:00:00.000000000 UTC, что на самом деле кажется допустимой датой..

То, что я думал до сих пор, делает что-то вроде этого:

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

1 ответ:

Как я могу установить индекс таким образом, что он удалит документ, если ключ expireAt действителен?

Пример задания индекса TTL с помощью mgo.v2 выглядит следующим образом:

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

Где приведенный выше пример устанавливает 120 секунд истечения. Смотрите такжеистечение срока действия данных из коллекций путем установки TTL .

Можно ли еще сделать так, чтобы некоторые документы вообще не истекали? Поскольку это поведение, я с нетерпением жду, чтобы получить коллекцию где некоторые документы действительно истекают, в то время как другие остаются постоянными

Вы можете указать флаг omitempty для поля структуры ExpireAt, как показано ниже:

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

, которые, по существу, включают поле только в том случае, если оно не имеет нулевого значения. Смотрите дополнительную информацию mgo.П2 зубров.Маршал

Теперь, например, вы можете вставить два документа, где один истекает, а другой сохраняется. Пример кода:
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)

Позже, вы можете установить поле expireAt С Update () , как пример:

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

Установка допустимого значения времени для поля expireAt, сделает его пригодным для индекса TTL. то есть больше не сохраняется.

В зависимости от вашего варианта использования, в качестве альтернативы вы можете также удалить() документ вместо обновления и полагаться на индекс TTL.