MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Tạo cấu trúc để tổng hợp

Khi tôi có một chút thời gian để suy nghĩ về điều này, tôi chạy về nhà để đọc perl và tìm ra điều này:

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

Vì vậy, quá trình này vô cùng đơn giản.

  1. Đi qua từng mục trong mảng và lấy khóa và giá trị cho mục nhập

  2. Tạo một "tài liệu" mới có đối số mảng cho khóa "$ cond" chỉ hai trong ba mục bắt buộc. Đây là các giá trị được chỉ định để kiểm tra "$ user_id" và giá trị "trọng số" được trả về.

  3. Kiểm tra độ dài của biến bên ngoài cho ngăn xếp và nếu nó trống (lần đầu tiên đến) thì hãy đẩy giá trị của 0 như đã thấy trong phần tử lồng nhau cuối cùng ở cuối khóa "$ cond" trong tài liệu.

  4. Nếu đã có thứ gì đó (chiều dài> 0) thì hãy lấy giá trị đó và đẩy nó là giá trị thứ ba trong khóa "$ cond" của tài liệu.

  5. Đặt lại tài liệu đó dưới dạng giá trị của ngăn xếp và lặp lại cho mục tiếp theo

Vì vậy, có một số điều trong danh sách chẳng hạn như đảo ngược thứ tự của đầu vào, điều này không bắt buộc nhưng tạo ra một thứ tự tự nhiên trong đầu ra lồng nhau. Ngoài ra, lựa chọn của tôi cho "ngăn xếp" bên ngoài đó là một mảng vì các toán tử kiểm tra có vẻ đơn giản. Nhưng nó thực sự chỉ là một giá trị đơn lẻ tiếp tục được sử dụng lại, tăng cường và thay thế.

Ngoài ra, việc in JSON chỉ ở đó để hiển thị đầu ra. Tất cả những gì thực sự muốn là giá trị kết quả của ngăn xếp được hợp nhất vào cấu trúc.

Sau đó, tôi chuyển đổi logic sang ruby, cũng như ngôn ngữ được OP sử dụng từ đó tôi lấy cảm hứng cho cách tạo cấu trúc lồng nhau này:

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

Và sau đó cuối cùng đến hình thức cuối cùng để tạo đường dẫn mà OP muốn:

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 )

Vì vậy, đó là một cách để tạo một cấu trúc được chuyển thành tổng hợp để áp dụng "trọng số" cụ thể cho một user_id và sắp xếp các kết quả trong bộ sưu tập.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Tổng hợp kết nối cơ sở dữ liệu Trình điều khiển Java MongoDB với Tomcat

  2. Mongoose - RangeError:Kích thước ngăn xếp cuộc gọi tối đa đã vượt quá

  3. MongoDB - Truy vấn phần tử cuối cùng của mảng?

  4. Quản lý cơ sở dữ liệu hiện đại:ClusterControl - Hướng dẫn

  5. mongodb di chuyển tài liệu từ bộ sưu tập này sang bộ sưu tập khác