1

これは一般的なユースケースのようです...しかし、どういうわけか私はそれを機能させることができません。

ユニークなアイテムを持つ列挙ストアとしてMongoDBを使用しようとしています。byte [] Id(一意のID)とタイムスタンプ(長い、列挙に使用される)を使用してコレクションを作成しました。ストアは非常に大きく(テラバイト)、さまざまなサーバーに分散しています。私はまだテスト段階にあるので、現在、ストアを最初から再構築することができます。

私がやりたいのは2つのことです。

  1. 挿入するアイテムごとに一意のIDを作成します。これは基本的に、同じIDを2回挿入すると、MongoDBがこれを検出してエラーを出すことを意味します。このアプローチはうまくいくようです。
  2. 他のプロセスによる新しいアイテムのストアを継続的に列挙します。私が採用したアプローチは、InsertIDに2番目のインデックスを追加し、サーバーIDとカウンター(一意で昇順にするため)とともに高精度のタイムスタンプを使用することでした。

最良のシナリオでは、これは、列挙子がすべてのサーバーのインデックスカーソルを追跡することを意味します。mongodbクエリ処理から学んだことから、この動作を期待していました。ただし、以下のコードを実行しようとすると、何かを取得するのに永遠に時間がかかるようです。

        long lastid = 0;
        while (true)
        {
            DateTime first = DateTime.UtcNow;
            foreach (var item in collection.FindAllAs<ContentItem>().OrderBy((a)=>(a.InsertId)).Take(100))
            {
                lastid = item.InsertId;
            }
            Console.WriteLine("Took {0:0.00} for 100", (DateTime.UtcNow - first).TotalSeconds);
        }

カーソルについて読みましたが、新しいアイテムがストアに挿入されたときに、カーソルが要件を満たしているかどうかわかりません。

私が言ったように、私はテーブル構造などに縛られていません...重要なのは、時間の経過とともに新しいアイテムを取得できることと、重複するアイテムを取得できないことだけです。

-ステファン。

4

1 に答える 1

0

どういうわけか私はそれを理解しました...多かれ少なかれ...

クエリを手動で作成し、次のような結果になりました。

db.documents.find({ "InsertId" : { "$gt" : NumberLong("2020374866209304106") } }).limit(10).sort({ "InsertId" : 1 });

質問に入れたLINQクエリは、このクエリを生成しません。コードを掘り下げた後、次の LINQ クエリであることがわかりました。

foreach (コレクション内の var item.AsQueryable().Where((a)=>(a.InsertId > lastid)).OrderBy((a) => (a.InsertId)).Take(100))

AsQueryable() は、LINQ to MongoDB クエリの書き換えを実行するためのキーのようです。

これにより結果が得られますが、まだ遅いように見えます (10 の結果で 4 秒、100 の結果で 30 秒)。ただし、「explain()」を追加すると、クエリの実行で「0 ミリ秒」に気付きました。

一括挿入と多田を実行するプロセスを停止しました。動作し、高速です。言い換えれば、私が抱えていた問題は、MongoDB のロック動作と、linq 実装の解釈方法が原因でした。前者はデータ ストアを最初にバルク フィルした結果であるため、これは問題が解決されたことを意味します。

解決策の「否定的な」部分について: シリアル化可能なカーソルなどを含む解決策をお勧めします...この「取る」解決策では、b ツリーを何度も反復する必要があります。誰かがこれに対する答えを持っているなら、私に知らせてください。

-ステファン。

于 2012-07-09T07:54:40.383 に答える