MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Membuat Struktur untuk Agregasi

Ketika saya memiliki waktu untuk memikirkan hal ini, saya berlari kembali ke rumah untuk mencari perl dan menyelesaikan ini:

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

Jadi prosesnya sangat sederhana.

  1. Telusuri setiap item dalam larik dan dapatkan kunci dan nilai untuk entri tersebut

  2. Buat "dokumen" baru yang memiliki argumen array ke kunci "$cond" hanya dua dari tiga entri yang diperlukan. Ini adalah nilai yang ditetapkan untuk menguji "$user_id" dan nilai "bobot" yang dikembalikan.

  3. Uji panjang variabel luar untuk tumpukan , dan jika kosong (pertama kali melalui) maka dorong nilai 0 seperti yang terlihat pada elemen bersarang terakhir di akhir kunci "$cond" dalam dokumen.

  4. Jika sudah ada sesuatu di sana (panjang> 0) maka ambil nilai itu dan dorong itu sebagai nilai ketiga dalam kunci "$cond" untuk dokumen.

  5. Masukkan kembali dokumen itu sebagai nilai tumpukan dan ulangi untuk item berikutnya

Jadi ada beberapa hal dalam daftar seperti membalikkan urutan input, yang tidak diperlukan tetapi menghasilkan urutan alami dalam output bersarang. Juga, pilihan saya untuk "tumpukan" di luar itu adalah array karena operator pengujian tampak sederhana. Tapi itu benar-benar hanya nilai tunggal yang terus digunakan kembali, ditambah dan diganti.

Juga pencetakan JSON hanya ada untuk menunjukkan output. Semua yang benar-benar diinginkan adalah nilai yang dihasilkan dari tumpukan untuk digabungkan ke dalam struktur.

Kemudian saya mengubah logika menjadi ruby, seperti bahasa yang digunakan oleh OP dari mana saya mendapat inspirasi tentang cara membuat struktur bersarang ini:

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

Dan akhirnya ke bentuk akhir untuk menghasilkan jalur pipa yang diinginkan 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 )

Jadi itulah cara untuk menghasilkan struktur yang akan diteruskan ke agregat untuk menerapkan "bobot" yang khusus untuk user_id dan urutkan hasilnya dalam koleksi.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Meteor:mengunggah file dari klien ke koleksi Mongo vs sistem file vs GridFS

  2. Node.js, Mongo menemukan dan mengembalikan data

  3. Bagaimana cara mengabaikan nol saat membongkar dokumen MongoDB?

  4. Array Mongodb $push dan $tarik

  5. Kursor MongoDB.hitung()