2017-01-18 1 views
0

私はデータベースとしてMongoDBを使用しています。MongoDBの列としてオートランキングを維持

私は列としてランクと名前を含むデータを持っています。新しい行は、既存のランクと異なるランクで更新することも、同じランクで更新することもできます。

同じ場合、他の行のランクを調整する必要があります。

挿入されるランクよりもランクの低い行は、1だけインクリメントされなければならず、ランクを持つ行はそのままにすることができます。

機能は、MS Wordタイプのアプリケーションで数字の箇条書きリストのようなものです。間に行を挿入する場合は、その下にある他の行の番号を調整します。

ランク1が最高ランクです。

3行あり

Name Rank 
A  1 
B  2 
C  3 

ここでは、名前としてDを、ランクとして2を更新したいと考えています。だから今行挿入後、DBはおそらくデータベースを使用して

Name Rank 
A  1 
B  3 
C  4 
D  2 

の下に好きなはずです、私は他の行を更新することによって、これを達成することができますトリガされます。

私が質問

のカップルが(a)はこのようなシナリオを実現するためのデータベース・トリガーを使用するよりも、他のより良い方法はありますか?すべての行を更新するのは時間のかかる作業です。

(b)MongoDBはネイティブでデータベーストリガーをサポートしていますか?

よろしく、

Saurav

答えて

1

いいえ、MongoDBは、(まだ)トリガを提供していません。また、私はトリガーが本当にこれを達成するための素晴らしい方法だとは思わない。

私はちょうどいくつかのアイデアを投げたい、それが意味を参照してください。

たぶん代わりにアプローチ1それらの多くの文書を乱す、あなたは1つのドキュメントのみ(のコレクションのランキングを呼びましょう)を持つコレクションを作成することができます。そのドキュメントでは、配列フィールド呼び出しのランクを設定してください。それは配列なのですでにシーケンスを維持しています。あなたは

db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["D"],$position:1}}}); 

第二の位置で、このランクにDを追加したい場合は

{ 
_id : "RANK", 
"ranks" : ["A","B","C"] 
} 

今ではインデックスは0から始まり考えると第二位置であるインデックス1にDを追加します。

{ 
_id : "RANK", 
"ranks" : ["A","D","B","C"] 
} 

しかし、あなたは4日から第一にCの位置を変更したい場合は、あなたが端からそれを削除し、最初にそれを置くために必要なものをキャッチが、そこにある、私は両方の動作を実現することはできません確信しています単一のアップデートで(多くのオプションで掘るなかった)ので、我々は { _idのように続いて、それは次のようになり2つのクエリ

db.ranking.update({_id:"RANK"},{$pull : {"ranks": "C"}}); 
db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["C"],$position:0}}}); 

を実行することができます:「RANK」、 は「ランク」:[「C」 、 "A"、 "D"、 "B"] }

は残りのシーケンスを維持します。

ここで、A、B、Cなどの代わりにIDを格納したいと思います.1つのドキュメントが16MBになることができるので、idはMongoDB ObjectIdがそれぞれ12バイトの場合、 。これで十分でない場合は、フォローアップ文書をさらにランキングするオプションがあります。

アプローチ2

あなたはまた、代わりに数値としてランクを有していると、ちょうどfollowedByとprecededByのように2枚のフィールドを持つことができます。

ので、あなたのユーザードキュメントは、第2の位置にDを追加したい場合は、その後、あなたは現在の第二の位置を変更する必要があり、それが変更になりますので、あなたは、新しいものを挿入する必要が

{ 
_id:"A" 
"followedBy":"B", 
} 
{ 
_id:"B" 
"followedBy":"C", 
"precededBy":"A" 
} 
{ 
_id:"c" 
"precededBy":"B", 
} 

を見てしまいますたった2つの文書

{ 
_id:"A" 
"followedBy":"B", 
} 
{ 
_id:"B" 
"followedBy":"C", 
"precededBy":"D" //changed from A to D 
} 
{ 
_id:"c" 
"precededBy":"B", 
} 
{ 
_id:"D" 
"followedBy":"B", 
"precededBy":"A" 
} 

に、このアプローチの欠点は、アプリケーション内のすべてのこれらを取得し、構造のLinkedListのソートを作成するまでとしない限り、あなたはランキングに基づいてクエリをで並べ替えることができないということです。

このアプローチは、DBの変更を最小限に抑えてランキングを保持するだけです。

+0

お返事ありがとうございました...私はオプション1を使用する予定です...名前よりもいくつかのデータがあるので...単一のドキュメントコレクションとマスターコレクションで巻き戻し検索を実行する必要があります – saurav

+1

アプローチ1は私の選択でもありました。文書の配列を維持するのは問題ありませんが、操作を実行するのが難しいため、それ以上のネストされた配列は入れないでください。 同様に、可能であれば、参照で集約を実行するのではなく、ranks配列内にドキュメントとしていくつかのフィールドを配置することをお勧めします。検索にはコストがかかりますが、集約自体には用語やメモリに制限があります。 –

+0

こんにちはRahul ...あなたの永続的な助けてくれてありがとう...私はあなたがランクコレクション内の文書の配列を作成することを意味すると思いますか?... – saurav

関連する問題