2013-08-28 27 views
0

我在輪軌4應用中使用輪胎和mongoid。mongoid即使目前+輪胎+ mongoid也沒有找到文檔

class Agent 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    include Mongoid::Taggable 
    include Tire::Model::Search 
    include Tire::Model::Callbacks 
    ... 
    mapping do 
    indexes :id, index: :not_analyzed 
    indexes :name, type: 'string', analyzer: 'pattern' 
    indexes :tags_array, type: 'string', analyzer: 'pattern' 
    end 
    ... 
    def self.search(params) 
    tire.search(load: true) do 
     query do 
     string "name:#{params}" 
     string "tags_array:#{params}" 
     end 
    end 
    end 
    ... 

有4劑,如

Agent.all.collect(&:tags) 
    => ["pune", "pune", "press", "pune press"] 
Agent.all.collect(&:name) 
    => ["agent smith", "first", "second", "third"] 

我有3個問題作爲

1)第一個問題是,所述試劑是不是由 '名稱' 進行搜索。

results = Agent.search('first') 
    => #<Tire::Results::Collection:0xb26dc4c @response={"took"=>1, "timed_out"=>false, "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0}, "hits"=>{"total"=>0, "max_score"=>nil, "hits"=>[]}}, @options={:load=>true, :size=>10}, @time=1, @total=0, @facets=nil, @max_score=0.0, @wrapper=Tire::Results::Item> 
results.results 
    => [] 

2)第二個問題是,mongoid給出的錯誤指定具有指定id的對象不存在。如果我搜索基於標籤

results = Agent.search('press') 
    => #<Tire::Results::Collection:0xb296da4 @response={"took"=>1, "timed_out"=>false, "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0}, "hits"=>{"total"=>2, "max_score"=>0.30685282, "hits"=>[{"_index"=>"agents", "_type"=>"agent", "_id"=>"{\"$oid\"=>\"521da715f94adc957d000005\"}", "_score"=>0.30685282, "_source"=>{"name"=>"second", "tags_array"=>["press"]}}, {"_index"=>"agents", "_type"=>"agent", "_id"=>"{\"$oid\"=>\"521da715f94adc957d000004\"}", "_score"=>0.19178301, "_source"=>{"name"=>"third", "tags_array"=>["pune press"]}}]}}, @options={:load=>true, :size=>10}, @time=1, @total=2, @facets=nil, @max_score=0.30685282, @wrapper=Tire::Results::Item> 

results.results 
    Mongoid::Errors::DocumentNotFound: 
    Problem: 
    Document(s) not found for class Agent with id(s) {"$oid"=>"521da715f94adc957d000005"}, {"$oid"=>"521da715f94adc957d000004"}. 
    Summary: 
    When calling Agent.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): {"$oid"=>"521da715f94adc957d000005"}, {"$oid"=>"521da715f94adc957d000004"} ... (2 total) and the following ids were not found: {"$oid"=>"521da715f94adc957d000005"}, {"$oid"=>"521da715f94adc957d000004"}. 

Agent.all.collect(&:id) 
    => ["521da715f94adc957d000007", "521da715f94adc957d000006", "521da715f94adc957d000005", "521da715f94adc957d000004"] 

3)如果我重新索引代理對象,在彈性搜索的ID比mongodb的對象ID

Agent.index_name 
    => "agents" 
Tire.index('agents').delete 
    => true 
Agent.import 
    => #<Tire::Model::Import::Strategy::Mongoid:0xb2dad9c @klass=Agent, @options={:per_page=>1000}, @index=#<Tire::Index:0xb2dabe4 @name="agents", @response=#<Tire::HTTP::Response:0xb30c4b4 @body="{\"took\":630,\"items\":[{\"create\":{\"_index\":\"agents\",\"_type\":\"agent\",\"_id\":\"h0k78SupT9GGTT3I6qV3Bw\",\"_version\":1,\"ok\":true}},{\"create\":{\"_index\":\"agents\",\"_type\":\"agent\",\"_id\":\"LuJMwJSFRquezRUc1HUpEg\",\"_version\":1,\"ok\":true}},{\"create\":{\"_index\":\"agents\",\"_type\":\"agent\",\"_id\":\"gE6MreF8T4ePdD8lqutSJQ\",\"_version\":1,\"ok\":true}},{\"create\":{\"_index\":\"agents\",\"_type\":\"agent\",\"_id\":\"4azbinLjSO2LuRXn9-WYtg\",\"_version\":1,\"ok\":true}}]}", @code=200, @headers={:content_type=>"application/json; charset=UTF-8", :content_length=>"426"}>>> 

results = Agent.search('press') 
    => #<Tire::Results::Collection:0xb31bcac @response={"took"=>5, "timed_out"=>false, "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0}, "hits"=>{"total"=>2, "max_score"=>1.0, "hits"=>[{"_index"=>"agents", "_type"=>"agent", "_id"=>"gE6MreF8T4ePdD8lqutSJQ", "_score"=>1.0, "_source"=>{"name"=>"second", "tags_array"=>["press"]}}, {"_index"=>"agents", "_type"=>"agent", "_id"=>"4azbinLjSO2LuRXn9-WYtg", "_score"=>0.19178301, "_source"=>{"name"=>"third", "tags_array"=>["pune press"]}}]}}, @options={:load=>true, :size=>10}, @time=5, @total=2, @facets=nil, @max_score=1.0, @wrapper=Tire::Results::Item> 
results.results 
    =>Mongoid::Errors::DocumentNotFound: 
    Problem: 
     Document(s) not found for class Agent with id(s) gE6MreF8T4ePdD8lqutSJQ, 4azbinLjSO2LuRXn9-WYtg. 

我已正確地定義的映射完全不同?用戶應該能夠基於代理名稱或/和標籤進行搜索。部分名稱也應該被允許。

== UPDATE

從elasticsearch映射爲localhost的結果:9200/_mapping漂亮= 1

"agents" : { 
    "agent" : { 
    "properties" : { 
     "id" : { 
     "type" : "string", 
     "index" : "not_analyzed", 
     "omit_norms" : true, 
     "index_options" : "docs" 
     }, 
     "name" : { 
     "type" : "string" 
     }, 
     "tags_array" : { 
     "type" : "string" 
     } 
    } 
    } 
} 

回答

0

我被搜索用於最後2天的上述問題的解決方案。最後,找到解決方案https://github.com/karmi/tire/issues/775

問題和解決方案的說明

> Agent.all.collect(&:name) 
    => ["first", "second", "third", "agent smith"] 

> Agent.all.collect(&:id) 
    => ["52204be3f94adc86b2000007", "52204be3f94adc86b2000006", "52204be3f94adc86b2000005", "52204be3f94adc86b2000004"] 

> Agent.all.collect(&:tags) 
    => ["press pune", "press", "pune", "matrix"] 

$ a = Agent.search('pu') 
=> #<Tire::Results::Collection:0xbb24cf0 @response={"took"=>1, "timed_out"=>false, "_shards"=>{"total"=>5, "successful"=>5, "failed"=>0}, "hits"=>{"total"=>2, "max_score"=>0.5, "hits"=>[{"_index"=>"agents", "_type"=>"agent", "_id"=>"{\"$oid\"=>\"52204be3f94adc86b2000005\"}", "_score"=>0.5, "_source"=>{"name"=>"third", "tags_array"=>["pune"]}}, {"_index"=>"agents", "_type"=>"agent", "_id"=>"{\"$oid\"=>\"52204be3f94adc86b2000007\"}", "_score"=>0.5, "_source"=>{"name"=>"first", "tags_array"=>["press pune"]}}]}}, @options={:load=>true, :size=>10}, @time=1, @total=2, @facets=nil, @max_score=0.5, @wrapper=Tire::Results::Item> 

2 results present for the above search. 

$ a.results 
=> 
    Mongoid::Errors::DocumentNotFound: 
Problem: 
Document(s) not found for class Agent with id(s) {"$oid"=>"52204be3f94adc86b2000005"}, {"$oid"=>"52204be3f94adc86b2000007"}. 

Summary: 
    When calling Agent.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): {"$oid"=>"52204be3f94adc86b2000005"}, {"$oid"=>"52204be3f94adc86b2000007"} ... (2 total) and the following ids were not found: {"$oid"=>"52204be3f94adc86b2000005"}, {"$oid"=>"52204be3f94adc86b2000007"}. 
Resolution: 
    Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples. 
    .... 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/bundler/gems/mongoid-85e146637503/lib/mongoid/findable.rb:88:in `find' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/tire-0.6.0/lib/tire/results/collection.rb:156:in `__find_records_by_ids' 
    .... 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/tire-0.6.0/lib/tire/results/collection.rb:144:in `block in __get_results_with_load' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/tire-0.6.0/lib/tire/results/collection.rb:131:in `each' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/tire-0.6.0/lib/tire/results/collection.rb:131:in `__get_results_with_load' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/tire-0.6.0/lib/tire/results/collection.rb:27:in `results' 
from (irb):2 


# method used in tire to retrieve the objects based on the id(s). id or array of ids. 
def __find_records_by_ids(klass, ids) 
    @options[:load] === true ? klass.find(ids) : klass.find(ids, @options[:load]) 
end 

https://github.com/mongoid/mongoid/blob/master/CHANGELOG.md 的mongoid 4的changelog指定

#2497 Calling to_json no longer tampers with the return value from the driver, and proper returns{ "$oid" : object_id.to_s } instead of just the string representation previously 

輪胎預計ID數組,但有一個散列作爲標識:{ 「$ OID」 =>「52204be3f94adc86b2000005」},{「$ oid」=>「52204be3f94adc86b2000007」}並試圖找到該對象爲

Agent.find({"$oid"=>"52204be3f94adc86b2000005"}, {"$oid"=>"52204be3f94adc86b2000007"}) #and hence the error. 

下面的代碼工作:

Agent.find("52204be3f94adc86b2000004", "52204be3f94adc86b2000007") 
Agent.find(["52204be3f94adc86b2000004", "52204be3f94adc86b2000007"]) 

Agent.all.collect(&:name).as_json 
=> ["first", "second", "third", "agent smith"] 

Agent.all.collect(&:id).as_json 
=> [{"$oid"=>"52204be3f94adc86b2000007"}, {"$oid"=>"52204be3f94adc86b2000006"}, {"$oid"=>"52204be3f94adc86b2000005"}, {"$oid"=>"52204be3f94adc86b2000004"}] 

臨時黑客:用添加初始化以下內容

require "tire" 
module Tire 
class Index 
    def get_id_from_document(document) #document is the object. ie agent object in the above case 
    case 
     when document.is_a?(Hash) 
     document[:_id] || document['_id'] || document[:id] || document['id'] 
     #if is not an hash and responds to 'id' and object_id is not equal to id "Agent.last.object_id => 96643940" 
     when document.respond_to?(:id) && document.id != document.object_id 
     document.id.to_s # was document.id.as_json 
     end 
    end 
    end 
end