MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Генериране на структура за агрегиране

Когато имах момент да помисля за това, изтичах вкъщи да 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] );

Така че процесът беше ослепително прост.

  1. Преминете през всеки елемент от масива и вземете ключа и стойността за записа

  2. Създайте нов "документ", който има в масива аргумент към ключа "$cond" само два от необходимите три записа. Това са стойностите, присвоени за тестване на „$user_id“ и върнатата стойност на „тегло“.

  3. Тествайте дължината на външната променлива за стека , и ако е било празно (за първи път), тогава натиснете стойността на 0 както се вижда в последния вложен елемент до края на ключа "$cond" в документа.

  4. Ако вече е имало нещо (дължина> 0), вземете тази стойност и натиснете го като трета стойност в ключа "$cond" за документа.

  5. Поставете този документ обратно като стойност на стека и повторете за следващия елемент

Така че има няколко неща в списъка, като например обръщане на реда на входа, което не е задължително, но създава естествен ред във вложения изход. Освен това моят избор за този външен "стек" беше масив, защото тестовите оператори изглеждаха прости. Но това наистина е просто уникална стойност, която непрекъснато се използва, увеличава и заменя.

Също така JSON печатът е там, за да покаже изхода. Всичко, което наистина се иска, е получената стойност на stack да бъдат обединени в структурата.

След това преобразувах логиката в ruby, както беше и езикът, използван от 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])

И след това в крайна сметка в окончателната форма, за да генерира тръбопровода, който ОП искаше:

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 и сортирайте резултатите в колекцията.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB - Какво ще кажете за десетичен тип стойност?

  2. Качване на файл Node.js (Express 4, MongoDB, GridFS, GridFS-Stream)

  3. Как да форматирате числа със запетаи в SQL

  4. Проверете дали MongoDB upsert направи вмъкване или актуализация

  5. Разбиране на Meteor Публикуване / Абониране