2015-12-18 2 views
0

Я пытаюсь найти Doc model has_and_belongs_to_many проекты, которые принадлежат к определенному проекту.Как искать Elasticsearch-рельсы с условиями модели ассоциации?

модели/doc.rb требуют 'elasticsearch/модель'

class Doc < ActiveRecord::Base 
    include Elasticsearch::Model 
    include Elasticsearch::Model::Callbacks 

    settings index: { 
    analysis: { 
     tokenizer: { 
     ngram_tokenizer: { 
      type: "nGram", 
      min_gram: "2", 
      max_gram: "3", 
      token_chars: [ 
      "letter", 
      "digit", 
      "punctuation" 
      ] 
     } 
     }, 
     analyzer: { 
     ngram_analyzer: { 
      tokenizer: "ngram_tokenizer" 
     } 
     }, 
    }, 
    } do 
     mappings do 
     indexes :sourcedb, type: 'string', analyzer: 'ngram_analyzer' 
     indexes :sourceid, type: 'string', analyzer: 'ngram_analyzer' 
     indexes :body, type: 'string', analyzer: 'ngram_analyzer' 
     indexes :docs_projects do 
      indexes :doc_id 
      indexes :project_id 
      indexes :projects do 
      indexes :id, index: :not_analyzed 
      end 
     end 
     end 
    end 

    def as_indexed_json(options={}) 
    as_json(
     only: [:id, :sourcedb, :sourceid, :body], 
     include: { projects: {only: :id} } 
    ) 
    end 
end 

метод поиска ниже

search_docs = docs.search(
    query: { 
     bool:{ 
     must: [ 
      {match: { 
       'projects.id' => project_id 
      } 
      } 
     ] 
     } 
    }, 
    size: 5000, 
).records.order('sourcedb ASC, sourceid ASC').paginate(page:params[:page], per_page: 10) 

Этот метод поиска заканчивается без ошибок, но ничего не вернулись.

Doc Load (4.6ms) SELECT "docs".* FROM "docs" INNER JOIN "docs_projects" ON "docs"."id" = "docs_projects"."doc_id" WHERE "docs_projects"."project_id" = 56 
    (0.4ms) SELECT COUNT(*) FROM "docs" WHERE 1=0 
    Doc Load (0.3ms) SELECT "docs".* FROM "docs" WHERE 1=0 ORDER BY sourcedb ASC, sourceid ASC LIMIT 10 OFFSET 0 
    CACHE (0.0ms) SELECT COUNT(*) FROM "docs" WHERE 1=0 

Я пытался искать с, где ([projects.id IN (?)], Project_ids), но он не может найти документы принадлежит к проекту с максимальным размером.
Как искать по совпадению с ассоциациями?
Спасибо заранее.

ответ

0

Теперь я нашел решение. Вот как я решил.

doc.rb

settings index: { 
    analysis: { 
     tokenizer: { 
     ngram_tokenizer: { 
      type: "nGram", 
      min_gram: "2", 
      max_gram: "3", 
      token_chars: [ 
      "letter", 
      "digit", 
      "punctuation" 
      ] 
     } 
     }, 
     analyzer: { 
     ngram_analyzer: { 
      tokenizer: "ngram_tokenizer" 
     } 
     }, 
    }, 
    } do 
     mappings do 
     indexes :sourcedb, type: 'string', analyzer: 'ngram_analyzer' 
     indexes :sourceid, type: 'string', analyzer: 'ngram_analyzer' 
     indexes :body, type: 'string', analyzer: 'ngram_analyzer' 

     # indexes :docs_projects, type: 'nested' do 
     indexes :docs_projects do 
      indexes :doc_id 
      indexes :project_id 
     end 

     indexes :projects do 
      indexes :id, index: :not_analyzed 
     end 
     end 
    end 

метод поиска

def self.search_docs(attributes = {}) 
    minimum_should_match = 0 
    minimum_should_match += 1 if attributes[:sourcedb].present? 
    minimum_should_match += 1 if attributes[:sourceid].present? 
    minimum_should_match += 1 if attributes[:body].present? 

    if attributes[:project_id].present? 
     must_array = [ 
     {match: { 
      'projects.id' => attributes[:project_id] 
      } 
     } 
     ] 
    end 

    docs = search(
     query: { 
     bool:{ 
      must: must_array, 
      should: [ 
      {match: { 
       sourcedb: { 
       query: attributes[:sourcedb], 
       fuzziness: 0 
       } 
      } 
      }, 
      {match: { 
       sourceid: { 
       query: attributes[:sourceid], 
       fuzziness: 0 
       } 
      } 
      }, 
      {match: { 
       body: { 
       query: attributes[:body], 
       fuzziness: 'AUTO' 
       } 
      } 
      }, 
      ], 
      minimum_should_match: minimum_should_match 
     } 
     }, 
     size: SEARCH_SIZE, 
    ) 
    return { 
     total: docs.results.total, 
     docs: docs.records.order('sourcedb ASC, sourceid ASC') 
    } 
    end 
Смежные вопросы