首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于弹性搜索的关联模型搜索方法[Ruby,ActiveRecord,Elasticsearch -模型]

基于弹性搜索的关联模型搜索方法[Ruby,ActiveRecord,Elasticsearch -模型]
EN

Stack Overflow用户
提问于 2020-02-19 09:07:04
回答 2查看 595关注 0票数 0

Elasticsearch搜索的情况下,我有一个关于选择最佳方法的问题。

我有Rails、ActiveRecordElasticsearch ( elasticsearch-model gem)。

这是一个返回projects (Project模型)的简单API,在这里我设置了索引:

代码语言:javascript
运行
复制
mapping dynamic: false do
indexes :created_at, type: 'date'
end

然后,我只需对Elasticsearch进行搜索,并直接从控制器返回AR关系。它运转得很好。

现在,我正在尝试将categories添加到projects中,如categories has_many projectsprojects belongs_to categories。我想知道两件事:

现在我应该如何进行一个查询来获取特定类别的项目,应该重新实现它以返回result = Category.search(...)并返回result.jobs,还是仍然通过projects查找,而通过category_id进行搜索?

如何将弹性搜索中的CategoryProject结合起来,使从特定类别和多个类别中搜索项目成为可能?合并映射?

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-19 11:30:56

我的第一个想法是用例非常简单。你根本不需要搜索。您可以简化和使用ActiveRecord、按SQL选择并返回记录。您不需要Elasticsearch为您的用例提供的任何特性,您只是通过这样做为自己创建了更多的工作。

但是,我将假设您的开发是迭代式的,您的使用将变得更加复杂。证明使用Elasticsearch是正当的。

关系数据和非关系数据

ActiveRecord是关系数据的奥姆。典型的https://www.elastic.co/guide/en/elasticsearch/reference/current/documents-indices.htmlly,它位于一个结构化查询语言驱动的关系数据库之上。它很好地支持关系( Rails术语中的关联)。

Elasticsearch是一个非关系文档存储,在反向索引中以JSON的形式存储信息。这允许非常快速的全文搜索(以及其他用途)。它不能很好地支持文档之间的关系。它被设计成不关联数据!它希望您不要存储关系,而是不断重复数据,这与SQL方法相反。这被称为去正规化,下面将详细介绍。

这些是非常不同的方式来考虑数据存储!这并不意味着他们在一起打得不好。如果使用得当,它们可以很好地结合在一起。然而,他们采取不同的思维方式。在我看来,重要的是要掌握好每个基本要素,以便对如何使用它们做出正确的判断。

Elasticsearch拥有great 文档。我建议你花几个小时阅读一下。

Elasticsearch是如何关联的?

在您的问题中,您关心的是一个基本的has-many关联,那么弹性如何处理这些关联呢?有什么选择吗?

主要有4种选择。我想你应该把你的数据放在这里。

我认为你想归还所有的项目,从某些类别。因此,您应该创建一个索引,其中包含每个类别的文档。每个类别都应该包含一个完整的项目列表。然后,您可以查询一个类别并返回它的所有项目。

这是一种方法。您的用例非常简单,我觉得这太过分了,您可以使用上面链接的Elasticsearch的4种主要选项中的任何一种来解决这个问题。或者理想情况下,根本不使用Elasticsearch。

如果您提供更多关于用例的详细信息,我将能够更多地讨论您可以使用的方法。

票数 1
EN

Stack Overflow用户

发布于 2020-02-19 12:23:58

//映射(嵌套类别)

代码语言:javascript
运行
复制
 mapping dynamic: false do
  indexes :created_at, type: 'date'
  indexes :categories, type: 'nested' do
    indexes :name, type: :text, analyzer: :english
  end 
 end

// json

代码语言:javascript
运行
复制
  def as_indexed_json(_options = nil)
  { 
   created_at: created_at,
   # in case project belong_to category  
   # categories: [category.name, Category::DEFAULT].map do ... 
   categories: categories.map do |category|
     {
       name: category.name
     }
   end
  } 
 end

//搜索函数(elasticsearch),用于按类别搜索项目

代码语言:javascript
运行
复制
def by_categories(categories)
  filters = []
  categories.each { |category|
    filters.push term: {"categories.name":category.name}
  }
  Project.__elasticsearch__.search(
     query: {            
        nested: {
           path: "categories",
           query: {
              bool: {
                 filter:{
                    bool:{
                        should:filters                                       
                    }
                  }
               }
            }
        }    
     }
  )
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60296524

复制
相关文章

相似问题

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