首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用关联模型条件搜索Elasticsearch-rails?

如何使用关联模型条件搜索Elasticsearch-rails?
EN

Stack Overflow用户
提问于 2015-12-18 21:30:44
回答 1查看 600关注 0票数 0

我正在尝试搜索属于特定项目的文档模型has_and_belongs_to_many项目。

model/doc.rb需要'elasticsearch/model‘

代码语言:javascript
复制
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

搜索方法如下

代码语言:javascript
复制
  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)

此搜索方法结束时没有错误,但没有返回任何内容。

代码语言:javascript
复制
  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

我试着用where(projects.id IN (?),project_ids)搜索,但它不能搜索属于最大尺寸的项目的文档。

如何通过关联匹配进行搜索?

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2016-01-04 11:29:25

现在,我找到了解决方案。这就是我解决问题的方法。

doc.rb

代码语言:javascript
复制
  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

搜索方法

代码语言:javascript
复制
  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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34356870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档