*** NoMethodError 异常:未定义的方法“_id”
*** NoMethodError Exception: undefined method `_id'
我正在开发 RubyOnRails 应用程序。我通过 Tire
gem 使用 Elasticsearch。 Elasticsearch 索引了 3 个模型。这些模型是 News、NewsTag 和 Categorization。 News 与 NewsTag 具有多对多关系,NewsTag 与分类具有多对多关系。所有这些模型都是 mongodb.
映射索引:-
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 并且模型(News)中定义了一些经常调用的方法之前,它工作得很好。所以我搜索了 wrapping the Item to be News 并且发现了一些有趣的东西。
将此行添加到 config/intializers/tire.rb
Tire.configure do
wrapper ProxyObject
end
和这个文件 app/models/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
这个解决方案在 Elasticsearch 上的教程项目中非常成功。这个解决方案使我能够调用模型方法。但是,它不适用于我的项目。我注意到一些可能很重要的事情。在新闻索引中。
获取localhost:9200/news/news/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_ids
嵌入了 news_tags
,而 news_tags
嵌入了 news
。所以,我觉得有某种递归。
我的问题是,当我在 @news
对象上应用任何方法时,甚至 count
,从搜索中检索到我收到错误消息
(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>
为什么我会收到此错误消息?
它甚至不是描述性的。我不知道问题出在哪里。所以,谁能帮帮我。
我找到了解决方案。在搜索查询中添加 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
谢谢大家
我正在开发 RubyOnRails 应用程序。我通过 Tire
gem 使用 Elasticsearch。 Elasticsearch 索引了 3 个模型。这些模型是 News、NewsTag 和 Categorization。 News 与 NewsTag 具有多对多关系,NewsTag 与分类具有多对多关系。所有这些模型都是 mongodb.
映射索引:-
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 并且模型(News)中定义了一些经常调用的方法之前,它工作得很好。所以我搜索了 wrapping the Item to be News 并且发现了一些有趣的东西。
将此行添加到 config/intializers/tire.rb
Tire.configure do
wrapper ProxyObject
end
和这个文件 app/models/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
这个解决方案在 Elasticsearch 上的教程项目中非常成功。这个解决方案使我能够调用模型方法。但是,它不适用于我的项目。我注意到一些可能很重要的事情。在新闻索引中。
获取localhost:9200/news/news/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_ids
嵌入了 news_tags
,而 news_tags
嵌入了 news
。所以,我觉得有某种递归。
我的问题是,当我在 @news
对象上应用任何方法时,甚至 count
,从搜索中检索到我收到错误消息
(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>
为什么我会收到此错误消息? 它甚至不是描述性的。我不知道问题出在哪里。所以,谁能帮帮我。
我找到了解决方案。在搜索查询中添加 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
谢谢大家