11

私は次のことを達成しようとしています:

私が所有するすべてのレコードを選択します。ここで、所有権は私が作成したオブジェクト、または私が管理するユーザーが作成したオブジェクトであり、ユーザー管理はユーザーを管理するユーザーの階層にある可能性があります

所有権は明らかに簡単で、所有者に対応する単純な ID で処理できます。ユーザー管理の階層は、ID の大規模なリストを手間をかけずに実行するのに少し困惑しています (明らかに、管理されているすべてのユーザーを検索し、IN 句などを使用してそれらのユーザーのいずれかによって作成されたすべてのオブジェクトをリストすることができます)。

理想的には、これがすべて 1 つのクエリで発生するため、通常のページングと条件が発生します。

私はそれを成し遂げるためにいくつかの数学があったかもしれないと考えていました.IDを何らかの方法でハッシュして、それらがコマンドチェーンの誰かによって所有されているかどうかを判断できる.

この種の参照はありますか?

明らかな何かが欠けていますか?

それが違いを生む場合はMongoDBを使用しますが、インスピレーションのために他のデータベースについて考えてみてください.

更新: 1,000,000 レコードの MongoDB コレクションを作成して、クエリの IN 句の管理可能な数のパラメーターを構成する正確なデータを取得しました。具体的な情報が入り次第報告します。

分析:

ruby-mongo-driver と ruby​​ ベンチマーク ライブラリを使用します。

1039944 レコードの MongoDB コレクション

レコードは次のように定義されます。

{
    first_name: String,
    last_name: String,
    email: String,
    phone: String,
    company: String,
    owner: BSON::ObjectId
 }

すべてのフィールドに対してランダムに生成された値。

Owner フィールドにはインデックスがあります。

次の条件でクエリを実行します。

conditions = {"owner" => { "$in" => id_list }}
opts = {skip: rand, limit: 100}

結果:

    # 10201 ids
    #              user     system      total        real
    # 0:       0.240000   0.000000   0.240000 (  0.265148)
    # 1:       0.240000   0.010000   0.250000 (  0.265757)
    # 2:       0.240000   0.000000   0.240000 (  0.267149)
    # 3:       0.240000   0.000000   0.240000 (  0.269981)
    # 4:       0.240000   0.000000   0.240000 (  0.270436)
    # Find:    0.240000   0.000000   0.240000 (  0.266709)


    # 5201 ids
    #              user     system      total        real
    # 0:       0.120000   0.000000   0.120000 (  0.133824)
    # 1:       0.120000   0.000000   0.120000 (  0.134787)
    # 2:       0.110000   0.000000   0.110000 (  0.133262)
    # 3:       0.110000   0.000000   0.110000 (  0.136046)
    # 4:       0.120000   0.000000   0.120000 (  0.141220)
    # Find:    0.130000   0.000000   0.130000 (  0.139110)

    # 201 ids
    #              user     system      total        real
    # 0:       0.010000   0.000000   0.010000 (  0.006044)
    # 1:       0.000000   0.000000   0.000000 (  0.004681)
    # 2:       0.010000   0.000000   0.010000 (  0.004578)
    # 3:       0.000000   0.000000   0.000000 (  0.007048)
    # 4:       0.010000   0.000000   0.010000 (  0.008487)
    # Find:    0.000000   0.000000   0.000000 (  0.005990)

    # 1 id (NOT using IN)
    #              user     system      total        real
    # 0:       0.000000   0.000000   0.000000 (  0.002868)
    # 1:       0.000000   0.000000   0.000000 (  0.004937)
    # 2:       0.010000   0.000000   0.010000 (  0.003151)
    # 3:       0.000000   0.000000   0.000000 (  0.002983)
    # 4:       0.000000   0.000000   0.000000 (  0.003313)
    # Find:    0.000000   0.000000   0.000000 (  0.002742)

クエリに 10k の ID のリストがあっても、パフォーマンスは非常に高速です。

4

1 に答える 1

2

決定するためにユーザー管理テーブルとの結合が必要な一連の可能な値からの値を持つ「列」に基づいて、MongoDB からレコードを「選択」しようとしている場合、NoSQL はあなたに不利に働いています...

ユーザー ID のリストがまだ管理可能な場合は、次のようなwhere ownerId in (?,?,?,?,?...)クエリを実行できます (最初にリストを決定した後)。

db.documents.find({owner:{$in: [1234, 2345, 4444, 77777, 99999]}})

NoSQL の方法はおそらく、ドキュメントに ownerId だけでなく、管理階層の完全なパスを含めるなどして、物事を非正規化することです。

{  _id: 'the document A',
   owner : 1234,
   managers: [ 2345, 4444, 77777, 99999 ]
}

もちろん、ユーザー階層が移動したときに更新する必要があります。

于 2011-11-21T05:31:04.633 に答える