私はダイモンの最初の答えと同じタイプで、sort
とlimit
を使っていました。 _idが生成される方法のために、特に、一部のドライバ(最下位部分のインクリメントの代わりに乱数を使用するドライバ)では、これはお勧めできません。それは第2のもの(最も小さい部分としてミリ秒のようなより小さなものとは対照的に)を持っていますが、最後の数は乱数である可能性があります。したがって、ユーザーが1秒に2回セーブした場合(おそらくそうは思われませんが、気づく価値はありません)、最終的に若干の最新のドキュメントで終わる可能性があります。
ObjectIDの構造の詳細については、http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-BSONObjectIDSpecificationを参照してください。
私はあなたの文書に明示のversionNumberフィールドを追加することをお勧めしますので、あなたはそうのように、そのフィールドを使用して、同様の方法で問い合わせることができます:
db.coll.find({documentId: <id>}).sort({versionNum: -1}).limit(1);
編集コメントで質問に答えるために
通常のDateTimeをMongoDBに直接格納することはできますが、MongoDBの「DateTime」形式でミリ秒の精度しか格納しません。これで十分なら、それは簡単です。
BsonDocument doc = new BsonDocument("dt", DateTime.UtcNow);
coll.Insert (doc);
doc = coll.FindOne();
// see it doesn't have precision...
Console.WriteLine(doc.GetValue("dt").AsUniversalTime.Ticks);
NETのDateTime(ティック)/タイムスタンプの精度は、あなたはそれが同じように、仕事を得るためにキャストの束を行うことができます。
BsonDocument doc = new BsonDocument("dt", new BsonTimestamp(DateTime.UtcNow.Ticks));
coll.Insert (doc);
doc = coll.FindOne();
// see it does have precision
Console.WriteLine(new DateTime(doc.GetValue("dt").AsBsonTimestamp.Value).Ticks);
更新を再び!
BsonTimestampの実際の使い方は、2番目の解像度で一意のタイムスタンプを生成するように見えます。だから、私はコードの最後の数行にあるように、あなたは実際にそれらを乱用するつもりはないし、実際には結果の順序を乱すだろう。 TickTime(100ナノ秒)の解像度でDateTimeを保存する必要がある場合は、mongodbでソート可能な64ビットのint "チック"を保存してから、DateTimeでラップしてくださいもう一度、データベース:
BsonDocument doc = new BsonDocument("dt", DateTime.UtcNow.Ticks);
coll.Insert (doc);
doc = coll.FindOne();
DateTime dt = new DateTime(doc.GetValue("dt").AsInt64);
// see it does have precision
Console.WriteLine(dt.Ticks);
パーフェクト、ありがとうダイモン。しかし、2番目のオプションに関して、新しいレコードがメイン文書コレクションに挿入されている場合、非正規化された "インデックス"コレクションをアトミックに挿入して更新するにはどうすればよいですか?最初のドキュメントのインデックスレコードが更新される前に別のドキュメントインスタンスを挿入できますか?それは理にかなっていますか?ドキュメントが変更されていないことを確認するには、findAndModify権限を使用できますか?私はそれが最新の_idを取得しているかと思います。それは要点ですか?再度、感謝します。 – sambomartin
MongoDBはRDBMSのようなトリガーをサポートしていないので、アプリケーション側でそれをしています。 findAndModifyを使用すると、id/timestampが低い文書を見つけ出し、更新して更新することができます。 findAndModifyはアトミックな操作であるため、新しい値が現在のものより若い場合にのみドキュメントを更新します。この方法では、同時更新について心配する必要はありません。 – Daimon
もう一度ありがとうございます。バージョン番号またはタイムスタンプを使用していると仮定すると、別のプロセスが別のドキュメントインスタンスを追加して「インデックス」ドキュメントを更新した場合、findAndModfyは失敗します。 findAndModifyは、バージョンが現在の更新よりも新しい(より大きい) "index" docを更新しようとします。これが起こったら、私は単に最新バージョンを入手してインデックス文書を再度更新しようとしますか?申し訳ありませんが何かを繰り返している場合は、私の心の中でそれを明確にしたい – sambomartin