Создание структуры для агрегирования

Итак, вот вопрос. Я хочу создать структуру данных, учитывая набор входных значений.

Поскольку это представление нескольких языков, рассмотрим список входных данных как массив пар ключ / значение. И поэтому массив Hash, Map, Dictionary или любой другой термин, который плавает на вашей лодке. Я буду хранить все обозначения здесь как JSON, надеясь, что это достаточно универсально для перевода / декодирования.

Итак, для ввода, скажем, имеем следующее:

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

Может быть, немного избыточно, но давайте придерживаться этого.

Поэтому из этого ввода я хочу перейти к этой структуре. Я даю целую структуру, но важная часть – это то, что возвращается для значения под «весом» :

 [ { "$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 ]} ]} ]} ]} }} ] 

Таким образом, решение, которое я ищу, заполняет содержимое структуры для «веса», как показано в структуре, используя вход, как показано.

Да, значения, которые выглядят как цифры в структуре, должны быть числами, а не строками, поэтому независимо от реализации языка, кодированная версия JSON должна выглядеть точно так же.

Альтернативно , дайте мне лучший подход, чтобы получить тот же результат назначения значений веса на основе совпадающего user_id .

Кто-нибудь есть подход к этому?

Был бы рад любой языковой реализации, поскольку я считаю, что справедливо видеть, как можно создать структуру.

Я постараюсь добавить себя, но клеймо идет к хорошим реализациям.

Счастливое кодирование.

Когда у меня был момент подумать об этом, я побежал домой к перлу и отработал это:

 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 предназначена для отображения вывода. Все, что действительно нужно, – это итоговое значение стека, которое должно быть объединено в структуру.

Затем я преобразовал логику в 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]) 

И затем, в конечном итоге, в окончательную форму для создания трубопровода, который нужен 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 и сортировать результаты в коллекции.

Сначала спасибо Нилу за вашу помощь в этом, эта тренировка отлично подходит для меня, и это очень быстро. Для тех, кто использует mongoid, это то, что я использовал для создания параметра веса, где Recommended_user_ids – это массив:

  def self.project_recommended_weight recommended_user_ids return {} unless recommended_user_ids.present? {:weight => create_weight_statement(recommended_user_ids.reverse)} end def self.create_weight_statement recommended_user_ids, index=0 return 0 if index == recommended_user_ids.count {"$cond" => [{ "$eq" => ["$user_id", recommended_user_ids[index]] },index+1,create_weight_statement(recommended_user_ids,index+1)]} end 

Поэтому, чтобы добавить это к конвейеру, просто объедините хеш следующим образом:

 {"$project" => {:id => 1,:posted_at => 1}.merge(project_recommended_weight(options[:recommended_user_ids]))} 
  • Получить имена всех ключей в коллекции
  • массивы нулевой длины
  • Может ли встроенный метод struct знать знания родителя / ребенка?
  • Реализация комментариев и комментариев в базе данных
  • инициализация массива c
  • Монгодская структура агрегации | Группировать по нескольким значениям?
  • Наследование структуры в C
  • Поиск по нескольким коллекциям в MongoDB
  • итерация вектора, удаление некоторых элементов, как я иду
  • Что делает ключевое слово «new» для структуры на C #?
  • Выполнение case-statement в структуре агрегации mongodb
  • Давайте будем гением компьютера.