2017-01-25 16 views
0

RubyOnRailsアプリケーションで作業しています。私はTire gemでElasticsearchを使用しています。 Elasticsearchは3つのモデルを索引付けしました。これらのモデルはNews、NewsTag、Categorizationです。ニュースはNewsTagと多対多の関係にあり、NewsTagはカテゴリ化と多対多の関係にあります。これらのモデルはすべてmongodbです。*** NoMethodError例外:未定義のメソッド `_id '

マッピングインデックス: -

mapping do 
     indexes :cover, analyzer: 'snowball' 
     indexes :title_en 
     indexes :title_ar 
     indexes :content_brief_ar 
     indexes :content_brief_en 
     indexes :body_ar 
     indexes :body_en 
     indexes :likes, type: 'nested' do 
     end 
     indexes :comments, type: 'nested' do 
     end 

     indexes :news_tags, type: 'nested' do 
      indexes :name_en, analyzer: 'snowball' 
      indexes :name_ar, analyzer: 'snowball' 
      indexes :categorizations, type: 'nested' do 
      indexes :ar_name, analyzer: 'snowball' 
      indexes :en_name, analyzer: 'snowball' 
      end 
     end 
     end 
     def to_indexed_json 
    { 
     cover: self.cover, 
     title_ar: self.title_ar, 
     title_en: self.title_en, 
     content_brief_ar: self.content_brief_ar, 
     content_brief_en: self.content_brief_en, 
     body_ar: self.body_ar, 
     body_en: self.body_en, 
     news_tags: self.news_tags, 
     likes: self.likes, 
     comments: self.comments 
    }.to_json 
    end 

私は検索方法が

@news = News.tire.search do 
     query do 
      nested path: 'news_tags' do 
      query do 
       boolean do 
        should {terms 'news_tags.categorization_ids', categorization_ids } 
       end 
      end 
      end 
     end 
     page = page_param.to_i 
     search_size = per_page_param.to_i 
     from (page - 1) * search_size 
     size search_size 
     end 

私は、検索結果の種類がニュースではないことに気づいたことまではうまく働いていたこと、それが項目で、頻繁に呼び出されるモデル(News)で定義されたいくつかのメソッドがあります。だから私はItemをニュースにするために検索し、興味深いものを見つけました。

このソリューションはElasticsearchのチュートリアルプロジェクトと非常に成功したのconfig/intializers/tire.rb

Tire.configure do  
    wrapper ProxyObject 
end 

と、このファイルアプリ/モデル/ proxy_object.rb

class ProxyObject < SimpleDelegator 
    delegate :class, :is_a?, :to => :_proxied_object 

    def initialize(attrs={}) 
    klass = attrs['_type'].camelize.classify.constantize 
    @_proxied_object = klass.new 
    _assign_attrs(attrs) 
    super(_proxied_object) 
    end 

    private 

    def _proxied_object 
    @_proxied_object 
    end 

    def _assign_attrs(attrs={}) 
    attrs.each_pair do |key, value| 
     unless _proxied_object.respond_to?("#{key}=".to_sym) 
     _proxied_object.class.send(:attr_accessor, key.to_sym) 
     end 
     _proxied_object.send("#{key}=".to_sym, value) 
    end 
    end 
end 

に次の行を追加します。このソリューションは私にモデルメソッドを呼び出すことができました。しかし、私のプロジェクトではうまくいきません。私は重要なことに気づいた。ニュースインデックス。

GETのはlocalhost:9200 /ニュース/ニュース/ 58889bbb6f6d613fff050000

{ 
    "_index": "news", 
    "_type": "news", 
    "_id": "58889bbb6f6d613fff050000", 
    "_version": 1, 
    "found": true, 
    "_source": { 
    "cover": "new2", 
    "title_ar": "new2", 
    "title_en": "new2", 
    "content_brief_ar": "new2", 
    "content_brief_en": "new2", 
    "body_ar": "<p>new2</p>\r\n", 
    "body_en": "<p>new2</p>\r\n", 
    "news_tags": [ 
     { 
     "_id": "56dec06769702d1578000000", 
     "categorization_ids": [ 
      "5888990f6f6d613fff000000" 
     ], 
     "created_at": "2016-03-08T14:07:03+02:00", 
     "name_ar": "صحة الطفل", 
     "name_en": "Baby Health", 
     "news_ids": [ 
      "56dec03569702d156a010000", 
      "5704f92769702d4c2b010000", 
      "574efc7969702d370a130000", 
      "578515d369702d4f11000000", 
      "58889bbb6f6d613fff050000", 
      "58889c3f6f6d613fff080000" 
     ], 
     "updated_at": "2016-03-08T14:07:03+02:00" 
     } 
    ], 
    "likes": [], 
    "comments": [] 
    } 
} 

あなたが気づくと、news_idsnews_tagsに埋め込まれ、そしてnews_tagsnewsに埋め込まれています。だから、ある種の再帰があると感じます。

は、私は、検索から取得してもcount@newsオブジェクト、上のいずれかの方法を適用すると、私はエラーメッセージを、持っている私の質問は

(byebug) @news.count 
    MOPED: 127.0.0.1:27017 COMMAND  database=admin command={:ismaster=>1} runtime: 1.9747ms 
    MOPED: 127.0.0.1:27017 UPDATE  database=nabda-net_staging collection=news_tags selector={"$and"=>[{"_id"=>{"$in"=>[]}}]} update={"$pull"=>{"news_ids"=>BSON::ObjectId('5888aaba6f6d6154d0000000')}} flags=[:multi] 
         COMMAND  database=nabda-net_staging command={:getlasterror=>1, :w=>1} runtime: 0.6387ms 
*** NoMethodError Exception: undefined method `_id' for #<Hash:0x00000004b78190> 

は、なぜ私は、このエラーメッセージが表示されますでしょうか? 説明的ではありません。私はどこに問題があるのか​​分からない。だから、誰でも私を助けることができます。

答えて

1

解決策が見つかりました。検索クエリにload: trueを追加すると、問題が解決されます。

@news = News.tire.search load: true do 
     query do 
      nested path: 'news_tags' do 
      query do 
       boolean do 
        should {terms 'news_tags.categorization_ids', categorization_ids } 
       end 
      end 
      end 
     end 
     page = page_param.to_i 
     search_size = per_page_param.to_i 
     from (page - 1) * search_size 
     size search_size 
     end 

ありがとうございました。

関連する問題