これについて考える瞬間があったとき、私は家に戻ってperlに戻り、これを解決しました:
use Modern::Perl;
use Moose::Autobox;
use JSON;
my $encoder = JSON->new->pretty;
my $input = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7 }, { 1 => 8 } ];
my $stack = [];
foreach my $item ( reverse @{$input} ) {
while ( my ( $key, $value ) = each %{$item} ) {
my $rec = {
'$cond' => [
{ '$eq' => [ '$user_id', int($key) ] },
$value
]
};
if ( $stack->length == 0 ) {
$rec->{'$cond'}->push( 0 );
} else {
my $last = $stack->pop;
$rec->{'$cond'}->push( $last );
}
$stack->push( $rec );
}
}
say $encoder->encode( $stack->[0] );
そのため、プロセスは非常に単純でした。
-
配列内の各項目を調べて、エントリのキーと値を取得します
-
「$cond」キーへの配列引数を持つ新しい「ドキュメント」を作成します。必要な3つのエントリのうち2つだけです。これらは、「$user_id」と返された「weight」値をテストするために割り当てられた値です。
-
スタックの外部変数の長さをテストします 、空の場合(最初から)、プッシュ
0
の値 ドキュメントの「$cond」キーの最後にネストされた要素に見られるように。 -
すでに何かがあった場合(長さ> 0)、その値を取得してプッシュ ドキュメントの「$cond」キーの3番目の値として使用します。
-
そのドキュメントをスタックの値として戻します 次の項目について繰り返します
したがって、入力の順序を逆にするなど、リストにはいくつかのことがあります。これは必須ではありませんが、ネストされた出力で自然な順序を生成します。また、テスト演算子は単純に見えたので、その外側の「スタック」に対する私の選択は配列でした。しかし、それは実際には、再利用され、増強され、置き換えられ続ける唯一の値です。
また、JSON印刷は、出力を表示するためだけにあります。本当に必要なのは、結果として得られるスタックの値だけです。 構造にマージされます。
次に、このネストされた構造を生成する方法のインスピレーションを得たOPで使用される言語と同様に、ロジックをルビーに変換しました。
require 'json'
input = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7 }, { 1 => 8 } ]
stack = []
input.reverse_each {|item|
item.each {|key,value|
rec = {
'$cond' => [
{ '$eq' => [ '$user_id', key ] },
value
]
}
if ( stack.length == 0 )
rec['$cond'].push( 0 )
else
last = stack.pop
rec['$cond'].push( last )
end
stack.push( rec )
}
}
puts JSON.pretty_generate(stack[0])
そして、最終的には、OPが必要とするパイプラインを生成するための最終的な形式になります。
require 'json'
userWeights = [ { 4 => 10 }, { 7 => 9 }, { 90 => 7}, { 1 => 8 } ]
stack = []
userWeights.reverse_each {|item|
item.each {|key,value|
rec = {
'$cond' => [
{ '$eq' => [ '$user_id', key ] },
value
]
}
if ( stack.length == 0 )
rec['$cond'].push( 0 )
else
last = stack.pop
rec['$cond'].push( last )
end
stack.push( rec )
}
}
pipeline = [
{ '$project' => {
'user_id' => 1,
'content' => 1,
'date' => 1,
'weight' => stack[0]
}},
{ '$sort' => { 'weight' => -1, 'date' => -1 } }
]
puts JSON.pretty_generate( pipeline )
これは、user_id
に固有の「重み」を適用するために集計に渡される構造を生成する方法でした。 コレクション内の結果を並べ替えます。