【问题标题】:Mongoid Aggregate result into an instance of a rails modelMongoid 将结果聚合到 Rails 模型的实例中
【发布时间】:2020-05-29 09:43:40
【问题描述】:

简介

纠正遗留代码,有一个对象LandingPage 的索引,其中大多数列应该是可排序的,但不是。这大部分已得到纠正,但很少有专栏一直给我带来麻烦。

这些列是需要聚合的列,因为基于其他文档的计数。为了简化问题的解释,我只讲其中一个,称为Visit,因为其余的代码只是重复。

代码获取已排序和分页的数据,然后使用LandingPage 方法修改每个对象,然后将 json 发回。已经是这样了,不能修改。

因此,我需要进行聚合(按Visit 计数对LandingPage 进行排序),然后将对象作为LandingPage 实例来让旧代码在它们上工作。

问题在于无法将 Mongoid::Document 转换为 LandingPage 实例

这是我得到的错误:

Mongoid::Errors::UnknownAttribute:
Message:
  unknown_attribute : message
Summary:
  unknown_attribute : summary
Resolution:
  unknown_attribute : resolution

这是我的代码:

def controller_function
    landing_pages = fetch_landing_page 
    landing_page_hash[:data] = landing_pages.map do |landing_page|
        landing_page.do_something
        # Do other things
    end
    render json: landing_page_hash
end

def fetch_landing_page
    criteria = LandingPage.where(archived: false)

    columns_name = params[:columns_name]
    column_direction = params[:column_direction]

    case order_column_name
    when 'visit'
      order_by_visits(criteria, column_direction)
    else
      criteria.order_by(columns_name => column_direction).paginate(
                   per_page: params[:length],
                   page: (params[:start].to_i / params[:length].to_i) + 1
                 )
    end

    def order_by_visit(criteria, order_direction)


  def order_by_visits(landing_pages, column_direction)
      LandingPage.collection.aggregate([
          { '$match': landing_pages.selector },
          { '$lookup': {
              from: 'visits',
              localField: '_id',
              foreignField: 'landing_page_id',
              as: 'visits'
          }},
          { '$addFields': {  'visits_count': { '$size': '$visits' }}},
          { '$sort': { 'visits_count': column_direction == 'asc' ? 1 : -1 }},
          { '$unset': ['visits', 'visits_count'] },
          { '$skip': params[:start].to_i },
          { '$limit': params[:length].to_i }
      ]).map { |attrs| LandingPage.new(attrs) { |o| o.new_record = false } }
  end
end

我尝试过的

  • 将控制台中的哈希复制并粘贴到LandingPage.new(attributes),实例已创建且有效。
  • 把attributes key从string改成symbole,还是不行。
  • 在返回数组的任何元素上使用 is_a?(hash) 都会返回 true。
  • 将其放入 json 中,然后返回到散列中。仍然有一个 Mongoid::Document。

如何使 Aggregate 的返回成为 LandingPage 的有效实例?

【问题讨论】:

    标签: ruby-on-rails ruby mongodb mongoid


    【解决方案1】:

    聚合管道由 Ruby MongoDB 驱动程序实现,而不是由 Mongoid 实现,因此不返回 Mongoid 模型实例。

    documentation 中给出了如何获取 Mongoid 模型实例的示例。

    【讨论】:

    • 感谢您的回答。它让我明白我必须重构代码,因为文档中提出的解决方案不允许直接从查询中进行排序,而是在之后进行排序。 jira.mongodb.org/browse/SERVER-7528
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 2012-08-25
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多