MongoDB, обновления и контроль истечения срока действия документа

Я работаю над проектом node.js. Я пытаюсь понять, как работает MongoDB. Я получаю данные ежечасно через файл cron. Я хотел бы, чтобы были уникальные данные, поэтому я использую обновление вместо вставки. Это прекрасно работает. Я хотел бы добавить вариант, что срок действия данных истекает через три дня. Мне непонятно, как это сделать.

В псевдокоде:

Настройте Vars, URL-адреса, пару глобальных переменных, lineNr=1, end_index=#, включая databaseUrl.

   MongoClient.connect(databaseUrl, function(err, db) {
    assert.equal(null, err, "Database Connection Troubles: " + err);
 **** db.collection('XYZ_Collection').createIndex({"createdAt": 1},
            {expireAfterSeconds: 120}, function() {});   **** (update)

   s = fs.createReadStream(text_file_directory + 'master_index.txt')
        .pipe(es.split())
        .pipe(es.mapSync(function(line) { 
                s.pause();  // pause the readstream
                lineNr += 1;
                getContentFunction(line, s); 
                if (lineNr > end_index) {
                    s.end();
                }
        })
        .on('error', function() {
            console.log('Error while reading file.');
        })
        .on('end', function() {
            console.log('All done!');
        })
    );

    function getContentFunction(line, stream){ 
        (get content, format it, store it as flat JSON CleanedUpContent)
        var go = InsertContentToDB(db, CleanedUpContent, function() {
            stream.resume();
        });
    }  

    function InsertContentToDB(db, data, callback)   
            (expiration TTL code if placed here generates errors too..)             
            db.collection('XYZ_collection').update({
                    'ABC': data.abc,
                    'DEF': data.def)
                }, {
                    "createdAt": new Date(),
                    'ABC': data.abc,
                    'DEF': data.def,
                    'Content': data.blah_blah
                }, {
                    upsert: true
                },
                function(err, results) {
                    assert.equal(null, err, "MongoDB Troubles: " + err);
                    callback();
                });
    }

Таким образом, db.collection('').update() с двумя полями формирует составной индекс, чтобы обеспечить уникальность данных. upsert = true позволяет вставлять или обновлять по мере необходимости. Мои данные сильно разнятся. Некоторый контент уникален, другой контент является обновлением ранее представленного. Я думаю, что эта уникальная функция вставки или обновления работает правильно. Информация из... и здесь

Что я действительно хотел бы добавить, так это автоматическое истечение срока действия документов в коллекции. Я вижу много контента, но не могу понять, как это реализовать.

Если я попытаюсь

db.collection('XYZ_collection')
  .ensureIndex( { "createdAt": 1 }, 
                { expireAfterSeconds: 259200 } );   // three days 

Ошибка

/opt/rh/nodejs010/root/usr/lib/node_modules/mongodb/lib/mongodb/mongo_client.js:390 throw err ^ Ошибка: невозможно использовать writeConcern без предоставленного обратного вызова в Db.ensureIndex (/opt/rh/nodejs010 /root/usr/lib/node_modules/mongodb/lib/mongodb/db.js:1237:11) в Collection.ensureIndex (/opt/rh/nodejs010/root/usr/lib/node_modules/mongodb/lib/mongodb/коллекция .js:1037:11) в tempPrice (/var/lib/openshift/56d567467628e1717b000023/app-root/runtime/repo/get_options_prices.js:57:37) в /opt/rh/nodejs010/root/usr/lib/node_modules /mongodb/lib/mongodb/mongo_client.js:387:15 в процессе._tickCallback (node.js:442:13)

Если я попытаюсь использовать createIndex, я получу эту ошибку...

`TypeError: Cannot call method 'createIndex' of undefined`  

Обратите внимание, что база данных полностью пуста через db.XYZ_collection.drop() Так что да, я новичок в вещах Mongo. Кто-нибудь понял, что мне нужно сделать? Одно замечание: меня очень смущает что-то Я читал: в отношении того, что вы не можете создать индекс TTL, если индексированное поле уже используется другим индексом. Я думаю, что я в порядке, но это не ясно для меня.

Есть некоторые ограничения на выбор индекса TTL: вы не можете создать индекс TTL, если проиндексированное поле уже используется в другом индексе. index не может иметь несколько полей. индексированное поле должно быть типа Date bson

Как всегда, большое спасибо за вашу помощь.

Обновление: я добавил код createIndex выше. С пустым обратным вызовом он проходит без ошибок, но система TTL вообще не может удалить записи, вздох.


person zipzit    schedule 08.03.2016    source источник
comment
Может показаться, что вы не обернули этот вызов функцией, аналогичной другим, и/или не вызываете его, передавая значение переменной db. Вам также явно не хватает обратного вызова для вызова .ensureIndex() (на самом деле следует использовать .createIndex() ), хотя это не текущая проблема. Нам не хватает контекста для вашего нового фрагмента кода, хотя легко сказать, что другой код был написан не вами.   -  person Blakes Seven    schedule 08.03.2016
comment
КСТАТИ. Здесь должно быть достаточно TTL, но указанный вами отрывок не имеет ничего общего с ошибкой. Ошибка возникает в контексте кода, который вы здесь не указали, и того, как вы это вызываете.   -  person Blakes Seven    schedule 08.03.2016
comment
@BlakesSeven спасибо за ваш ответ. Итак, createIndex --› не определено. Я нигде не объявляю содержание БД, оно создано с помощью функции MongoClient.connect(). Будет ли распространяться ошибка «undefined», если коллекция БД нигде не существует? Помнишь, я вытер вещь начисто. Первое использование update вставляет первый документ в «новую» коллекцию. Это корень моей проблемы?   -  person zipzit    schedule 08.03.2016
comment
Как я уже сказал, посмотрите на другие функции в вашем списке, такие как function InsertContentToDB(db, data, callback). Код, который вы цитируете, должен быть (должен быть) обернут чем-то подобным. Вы не показываете нам этого, и именно в этом может заключаться ваша проблема. Во-вторых, посмотрите, где в вашем коде используются вызовы чего-то вроде InsertContentToDB. Что-то передается в качестве первого аргумента db, чего, вероятно, не хватает в вашем новом коде. Опять же, мы не можем увидеть этот код в вашем вопросе, и именно в этом ваша проблема.   -  person Blakes Seven    schedule 08.03.2016
comment
Поэтому я добавил простой пустой обратный вызов, и сообщения об ошибках исчезли. Я сейчас тестирую. Одна вещь. Публикуется ли сообщение createIndex один раз для каждого документа или один раз для коллекции? Я предполагаю, что это один раз за коллекцию, но мне это не ясно. Мой фактический код db.collection('XYZ_collection').createIndex({ "createdAt": 1 }, { expireAfterSeconds: 120 }, function() {});, но он, похоже, не работает. Подтвердит ли журнал Mongo, что система TTL жива?   -  person zipzit    schedule 08.03.2016
comment
Виноват. Я снова прочитал эту статью. еще несколько раз. Он говорит, что через минуту после истечения срока действия элементы умирают, и установка коллекции должна перехватывать документы, вставленные до CreateIndex(). Это подразумевает, что вызов функции необходим только один раз для каждой коллекции... Плохо. О, и о чем запись журнала note: noprealloc may hurt performance in many applications?   -  person zipzit    schedule 08.03.2016