2016-09-06 13 views
0

モデルCと1対1の関係を持つモデルBと1対多の関係を持つモデルAがあるとします。モデルCには数値を保持する属性Xがあります。これは、以下に説明する:グループ内のDjangoクエリの相違

models illustration

私はそれに関連するモデルの属性X Cの(モデルB経由)が一定の割合を持っているモデルAのすべてのインスタンスを望むクエリを表現するための最良の方法は何ですかその違いは?例えば

Iは、任意の関連するモデルCのX属性が20%以上の差を有する全てのAたい:

MODELA [ID = 1]

モデルBsを[ B1:C:attrX => 10、A1:B2:C:attrX => 14、A1:B3:C:attrX値> A1:B1、A1:B2、A1:B3>

モデルCs attr x値[ attrX => 13]

この例では、 ause A1:B1:C:attrXは、少なくとも1つの他のattrX

EDIT 1と20%以上の差があります。他の場合

をIはまた、B又はAでグループ化された全てのモデルCsに興味がありますクエリは実行可能ではありません。

あるいはAでグループ化されたすべてのモデルBsが...

答えて

1

私が欲しいAのためのCxのいずれかが、その後確実にMAXとMINを20%の差異がある場合は、関連するモデルCのX属性のいずれかが20%

以上の差を持っているすべてのAさんそのAのCxは少なくとも%20以上の差があります。あなたはその事実についてあなたの質問を構築することができます。 aggregate expressions使用しますが、このような何かを行うことができます。

もちろんBの
A.objects.annotate(
     max_diff=(Max('b__c__x') - Min('b__c__x')) * 100/Min('b__c__x') 
    ).filter(max_diff__gte=20) 

は、Cは、多くの関係に外国人や多くのための関連の名前を表します。これは最初にAオブジェクトにパーセントでmax_diffと注釈を付けてから、その値でフィルタリングします。フィールドの種類によっては、output_fieldも指定する必要があります。

問題の詳細はわかりませんが、aggregation functionsを確認することをおすすめします。標準偏差や分散が役立つかもしれません。

参考:

0

必ずそれらのカウントが内にする必要があります(これは、ORMでなんとかなるかもしれないが、それは混乱になる事の並べ替えのように聞こえますそれらのすべての平均の20%が彼らの呼び出しの数と同じです)。プリフェッチのための素晴らしい機会のようです。たぶん

for a in A.objects.prefetch_related("b_set__c"): 
    cs = [b.c for b in a.b_set.all()] 

のようなものと、あなたはそれがもう少し検査可能になりますとクエリのみの有限数を実行すべきPythonであなたのフィルタリングを適用することができます。唯一の問題は、あなたのクエリーセットがこの結果のために完全に反復するには大きすぎるとは思わないことです。

この方法ではうまくいかない場合は、変動の少ない基準に合うかどうかを示す列を追加して、BCというインスタンスを保存するときに更新する方が良いでしょう。

+0

頻繁に更新される程度10M項目、があります。私はPostgresを持っているORMソリューションが重い持ち上げをするのが望ましいと思います。 –

関連する問題