更新クエリ内でドキュメントの既存のフィールドを使用することはできません。ここにいくつかのオプションがあります。
存続時間コレクション:
有効期限が切れたときにドキュメントを削除する場合は、Time to Live コレクションを使用できます。Time to live コレクションでは、ドキュメントは指定された期間が経過すると自動的に削除されます。つまり、"Expires" フィールドと "MaxAge" フィールドを完全に削除できます。
有効期間が 30 秒の TTL インデックスを作成します。
mongos> db.last.ensureIndex({ "LastAccess" : 1 }, { "expireAfterSeconds" : 30 })
ドキュメントを挿入します。
mongos> db.last.insert({ "Value" : "No Expiration" })
mongos> db.last.insert({ "Value" : "Expiration", "LastAccess": new Date() })
mongos> db.last.find()
{ "_id" : ObjectId("505d15ac283b060dbc637ec0"), "Value" : "No Expiration" }
{ "_id" : ObjectId("505d15b1283b060dbc637ec1"), "Value" : "Expiration", "LastAccess" : ISODate("2012-09-22T01:34:41.102Z") }
15 秒間スリープします。
mongos> sleep(15000)
null
mongos> db.last.find()
{ "_id" : ObjectId("505d15ac283b060dbc637ec0"), "Value" : "No Expiration" }
{ "_id" : ObjectId("505d15b1283b060dbc637ec1"), "Value" : "Expiration", "LastAccess" : ISODate("2012-09-22T01:34:41.102Z") }
アクセス時間を更新します。
mongos> db.last.update({ "Value" : "Expiration" }, { "$set" : { "LastAccess" : new Date() }})
mongos> sleep(15000)
null
両方のドキュメントはまだ残っています:
mongos> db.last.find()
{ "_id" : ObjectId("505d15ac283b060dbc637ec0"), "Value" : "No Expiration" }
{ "LastAccess" : ISODate("2012-09-22T01:35:07.629Z"), "Value" : "Expiration", "_id" : ObjectId("505d15b1283b060dbc637ec1") }
30 秒間スリープします。
mongos> sleep(30000)
null
現在、有効期限のないドキュメントのみが存在します。
mongos> db.last.find()
{ "_id" : ObjectId("505d15ac283b060dbc637ec0"), "Value" : "No Expiration" }
ドキュメントを削除するプロセスは1 分間に 1 回しか実行されないことに注意してください。そのため、何かが削除される時間は、実際の有効期限の 1 分後になる場合があります。
2 つの検索と変更の呼び出し:
必要な値を含むドキュメントを挿入します。
mongos> db.last.insert({"Value":"oldvalue","LastAccess":new Date(),"Expires":new Date((new Date()).valueOf() + 3200),"MaxAge":3200,InProgress:false})
mongos> db.last.find()
{ "_id" : ObjectId("505b89292271f63498810600"), "Value" : "oldvalue", "LastAccess" : ISODate("2012-09-20T21:22:49.637Z"), "Expires" : ISODate("2012-09-20T21:22:52.837Z"), "MaxAge" : 3200, "InProgress" : false }
InProgress フィールドを変更して、MaxAge フィールドを見ていることを他の人に警告します (これを行っている間に誰かが MaxAge フィールドを変更しても構わない場合は、InProgress フィールドは必要なく、単に検索を実行できます)このステップ):
mongos> doc = db.last.findAndModify({ "query" : { "Value" : "oldvalue", "InProgress" : false }, "update" : { "$set" : { "InProgress" : true } } });
{
"_id" : ObjectId("505b89292271f63498810600"),
"Value" : "oldvalue",
"LastAccess" : ISODate("2012-09-20T21:22:49.637Z"),
"Expires" : ISODate("2012-09-20T21:22:52.837Z"),
"MaxAge" : 3200,
"InProgress" : false
}
mongos> db.last.find()
{ "_id" : ObjectId("505b89292271f63498810600"), "Value" : "oldvalue", "LastAccess" : ISODate("2012-09-20T21:22:49.637Z"), "Expires" : ISODate("2012-09-20T21:22:52.837Z"), "MaxAge" : 3200, "InProgress" : true }
ドキュメントを実際に新しい有効期限で更新し、InProgress を false に設定して、MaxAge をもう見ていないことを示します。
mongos> db.last.findAndModify({ "query" : { "Value" : "oldvalue", "InProgress" : true }, "update" : { "$set" : { "Value" : "newvalue", "LastAccess" : new Date(), "Expires" : new Date((new Date()).valueOf() + doc.MaxAge), "InProgress" : false } }, "new" : true });
{
"_id" : ObjectId("505b89292271f63498810600"),
"Value" : "newvalue",
"LastAccess" : ISODate("2012-09-20T21:23:29.058Z"),
"Expires" : ISODate("2012-09-20T21:23:32.258Z"),
"MaxAge" : 3200,
"InProgress" : false
}
デシベル.eval():
db.eval() もここで使用できますが、パフォーマンス上の理由から避ける必要があります