生成聚合结构 [英] Generating a Structure for Aggregation

查看:73
本文介绍了生成聚合结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个问题.我想做的是根据给定的一组输入值生成一个数据结构.

So here's a question. What I want to do is generate a data structure given a set of input values.

由于这是一种多语言提交,因此我们将输入列表视为键/值对的数组.因此,由一系列哈希,地图,字典或任何使您的船只漂浮的术语组成.我将所有表示法都保留为JSON,希望它具有足够的通用性以进行翻译/解码.

Since this is a multiple language submission, let's consider the input list to be an array of key/value pairs. And therefore an array of Hash, Map, Dictionary or whatever term that floats your boat. I'll keep all the notation here as JSON, hoping that's universal enough to translate / decode.

因此,输入以下内容:

[ { "4": 10 }, { "7": 9 }, { "90": 7 }, { "1": 8 } ] 

也许有点多余,但是我们坚持下去.

Maybe a little redundant, but lets stick with that.

因此,从该输入中,我想进入此结构.我给出了一个整体结构,但重要部分是在"weight" 下得到的值的返回值:

So from that input, I want to get to this structure. I'm giving a whole structure, but the important part is what gets returned for the value under "weight":

[
   { "$project": {
       "user_id": 1,
       "content": 1,
       "date": 1,
       "weight": { "$cond": [
           { "$eq": ["$user_id": 4] },
           10,
           { "$cond": [ 
               { "$eq": ["$user_id": 7] },
               9,
               { "$cond": [
                   { "$eq": ["$user_id": 90] },
                   7,
                   { "$cond": [
                       { "$eq": ["$user_id": 1] },
                       8, 
                       0
                   ]}
               ]}
           ]}
       ]}
   }}
]

因此,我正在寻找的解决方案使用如图所示的输入来填充结构中所示重量"的结构内容.

So the solution I'm looking for populates the structure content for "weight" as shown in the structure by using the input as shown.

是的,结构中看起来像的值必须是数字,而不是字符串,因此,无论采用哪种语言实现,JSON编码版本必须看起来都完全相同.

Yes the values that look like numbers in the structure must be numbers and not strings, so whatever the language implementation, the JSON encoded version must look exactly the same.

或者,请给我一种更好的方法,以达到基于匹配的user_id分配 weight 值的相同结果.

Alternately, give me a better approach to get to the same result of assigning the weight values based on the matching user_id.

有人有办法吗?

我会对任何语言的实现感到满意,因为我认为公正地了解如何创建结构是很公平的.

Would be happy with any language implementation as I think it is fair to just see how the structure can be created.

我会尝试添加自己,但是对良好的实现表示敬意.

I'll try to add myself, but kudos goes to the good implementations.

快乐的编码.

推荐答案

当我有时间考虑这个问题时,我回到了perl并解决了这个问题:

When I had a moment to think about this, I ran back home to perl and worked this out:

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] );

所以过程非常简单.

  1. 遍历数组中的每个项目并获取条目的键和值

  1. Go through each item in the array and get the key and value for the entry

创建一个新的文档",该文档在数组"$ cond"键的参数中仅需要三个条目中的两个.这些是为测试"$ user_id"和返回的"weight"值而分配的值.

Create a new "document" that has in array argument to the "$cond" key just two of required three entries. These are the values assigned to test the "$user_id" and the returned "weight" value.

测试 stack 的外部变量的长度,如果该变量为空(第一次),则 push 0的值,如下所示在文档中"$ cond"键末尾的最后一个嵌套元素中.

Test the length of the outside variable for stack, and if it was empty (first time through) then push the value of 0 as seen in the last nested element to the end of the "$cond" key in the document.

如果已经有东西(长度> 0),则取该值并将其推入作为文档"$ cond"键中的第三个值.

If there was something already there (length > 0) then take that value and push it as the third value in the "$cond" key for the document.

将该文档作为 stack 的值放回去,并重复下一个项目

Put that document back as the value of stack and repeat for the next item

因此,清单中有一些事情,例如反转输入的顺序,这不是必需的,但会在嵌套输出中产生自然顺序.另外,我对外部堆栈"的选择是一个数组,因为测试操作符看起来很简单.但这确实是一个奇异的价值,不断得到重复使用,扩充和替换.

So there are a few things in the listing such as reversing the order of the input, which isn't required but produces a natural order in the nested output. Also, my choice for that outside "stack" was an array because the test operators seemed simple. But it really is just a singular value that keeps getting re-used, augmented and replaced.

JSON打印也在那里,以显示输出.真正需要的只是将 stack 的结果值合并到结构中.

Also the JSON printing is just there to show the output. All that is really wanted is the resulting value of stack to be merged into the structure.

然后,我将逻辑转换为红宝石,就像OP所使用的语言一样,从中我得到了如何生成此嵌套结构的灵感:

Then I converted the logic to ruby, as was the language used by the OP from where I got the inspiration for how to generate this nested structure:

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所需的管道:

And then eventually into the final form to generate the pipeline that the OP wanted:

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的权重"并对排序结果进行排序.

So that was a way to generate a structure to be passed into aggregate in order to apply "weights" that are specific to a user_id and sort the results in the collection.

这篇关于生成聚合结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆