5

OrientDB グラフで次のモデルを想定します。

プロファイル頂点があります。プロファイルは 2 つのエッジで接続されています: LikedCommented。両方のエッジには、アクションのカウント (またはエッジの「重み」) を示す「値」フィールドがあります。

したがって、ユーザー A がユーザー B の投稿に 3 回コメントした場合、ユーザー A からユーザー B への値 = 3のコメント付きエッジが存在します。

ここで、ユーザー B と対話したすべてのユーザー (いいね! またはコメント) を、対話の重みで並べ替えて取得したいとします。次のSQLでそれを行うことができます:

select * from (traverse out from   
(select out, sum(value) as value from    
(traverse * from (select from Profile where username="B") while $depth < 3)    
where @class="Liked" or @class="Commented" group by out order by value desc)   
while $depth < 2  ) where @class="Profile" )

しかし、相互作用の重みも知りたい場合はどうすればよいでしょうか? 最後のトラバースを実行中に「値」を伝播するにはどうすればよいですか?

編集

提案によると、このクエリの簡略化されたバージョンは次のようになります。

select expand(out) from (    
    select out, sum(value) as value from (    
       select expand(inE("Liked", "Commented")) from Profile 
           where username="B"    
    ) group by out order by value desc 
)

しかし、LET を使用して外側の展開されたオブジェクトに値を挿入する方法がまだ見つかりません。$parent は、最も外側の選択で展開されているオブジェクトを指していないようです。

編集 2

私は思いつくあらゆる方法で $parent と遊んでいます。この場合、どのように使用できるかわかりません。繰り返しますが、私が解決しようとしている問題は、合計(値)を外部の結果セットに渡す方法です。GROUP BY を実行するときに LET を使用する方法がわかりません。また、最も外側の選択が拡張を実行しているときに LET を使用する方法もわかりません (他のプロジェクションを一緒に実行できないため)。拡大)。

また、$current を使用した結果は、期待どおりではないようです。たとえば、次のクエリです。

select expand($v) from    
   (select from    
      (select expand(inE("Liked", "Commented")) from Profile where @rid=#11:0)   
    let $v  = $current   
   )

これを返します:

{  
   "result" : [{  
       "@type" : "d",
        "@rid" : "#14:4",
        "@version" : 2,
        "@class" : "Commented",
        "value" : 1,
        "out" : "#11:165",
        "in" : "#11:0"
    }, {
        "@type" : "d",
        "@rid" : "#14:4",
        "@version" : 2,
        "@class" : "Commented",
        "value" : 1,
        "out" : "#11:165",
        "in" : "#11:0"
    }, {
        "@type" : "d",
        "@rid" : "#14:4",
        "@version" : 2,
        "@class" : "Commented",
        "value" : 1,
        "out" : "#11:165",
        "in" : "#11:0"
    }
]
}

すべてのエッジではなく、同じノードが何度も繰り返されます。これは私が期待することです。

4

2 に答える 2

3

古いバージョンの OrientDB を使用しているようです。最近のバージョンでは、それを簡素化できます。例: 元のクエリ:

select * from (
 traverse out from (
  select out, sum(value) as value from (
   traverse * from (
    select from Profile where username="B"
   ) while $depth < 3
  ) where @class="Liked" or @class="Commented" group by out order by value desc
 ) while $depth < 2 
) where @class="Profile" )

次のような Edge のラベル/クラスを渡す out()/in()/both() を使用して、いくつかのステップをスキップできます。

select expand( out(["Liked","Commented]) ) from Profile where username="B"

ただし、値を渡すには、LET 句で変数を使用できます。例:

select from XXX let $parent.a = value

このようにして、変数「a」を上位レベルのコンテキストに設定しますが、次のこともできます。

select from XXX let $parent.$parent.a = value

2レベル上に設定します。

于 2013-11-11T10:50:37.013 に答える