代码之家  ›  专栏  ›  技术社区  ›  vinibrsl

如何使用点符号访问有嚼劲的结果?

  •  0
  • vinibrsl  · 技术社区  · 8 年前

    Toptal's Chewy gem

    我在用 Chewy 以及ElasticSearch6、RubyonRails5.2和ActiveRecord。

    我的索引定义如下:

    class OrdersIndex < Chewy::Index
      define_type Order.includes(:customer) do
    
        field :id, type: "keyword"
    
        field :customer do
          field :id, type: "keyword"
          field :name, type: "text"
          field :email, type: "keyword"
        end
      end
    end
    

    我的模特:

    class Order < ApplicationRecord
      belongs_to :customer
    end
    

    这里的问题是,当我使用Chewy执行任何查询时,客户数据被反序列化为散列而不是对象,并且我不能使用点符号来访问嵌套数据。

    results = OrdersIndex.query(query_string: { query: "test" })
    results.first.id
    # => "594d8e8b2cc640bb78bd115ae644637a1cc84dd460be6f69"
    
    results.first.customer.name
    # => NoMethodError: undefined method `name' for #<Hash:0x000000000931d928>
    
    results.first.customer["name"]
    # => "Frederique Schaefer"
    

    如何使用点表示法访问嵌套关联( result.customer.name )? 或者反序列化对象(如结构)中的嵌套数据,这允许我使用点表示法?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Rahul Sharma    8 年前

    尝试使用

    results = OrdersIndex.query(query_string: { query: "test" }).objects
    

    如果要将现有的ES嵌套对象转换为可访问的点表示法,请尝试引用此答案。openstruct是在ruby中完成任务的最佳方法。

    Unable to use dot syntax for ruby hash

    也, this 一个人也可以帮忙

    this 如果需要openStruct处理嵌套对象,请链接

        2
  •  0
  •   vinibrsl    8 年前

    将刚刚反序列化的结果转换为JSON字符串,并使用OpenStruct作为 object_class 可能是一个坏主意,有一个很大的CPU成本。

    Struct ,保持着咀嚼宝石的懒惰。

    def convert_to_object(keys, values)
      schema = Struct.new(*keys.map(&:to_sym))
      object = schema.new(*values)
    
      object.each_pair do |key, value|
        if value.is_a?(Hash)
          object.send("#{key}=", convert_to_object(value.keys, value.values))
        end
      end
    
      object
    end
    
    OrdersIndex.query(query_string: { query: "test" }).lazy.map do |item|
      convert_to_object(item.attributes.keys, item.attributes.values)
    end
    

    convert_to_object

    对于懒惰,这是我用过的最酷的部分 Enumerator::Lazy 和 Enumerator#map 将\u转换为\u对象

    代码非常通用,适用于我得到的每个索引。

    推荐文章