在Elasticsearch
搜索的情况下,我有一个关于选择最佳方法的问题。
我有Rails、ActiveRecord
和Elasticsearch
( elasticsearch-model
gem)。
这是一个返回projects
(Project模型)的简单API,在这里我设置了索引:
mapping dynamic: false do
indexes :created_at, type: 'date'
end
然后,我只需对Elasticsearch进行搜索,并直接从控制器返回AR关系。它运转得很好。
现在,我正在尝试将categories
添加到projects
中,如categories has_many projects
和projects belongs_to categories
。我想知道两件事:
现在我应该如何进行一个查询来获取特定类别的项目,应该重新实现它以返回result = Category.search(...)
并返回result.jobs
,还是仍然通过projects
查找,而通过category_id
进行搜索?
如何将弹性搜索中的Category
和Project
结合起来,使从特定类别和多个类别中搜索项目成为可能?合并映射?
提前感谢!
发布于 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。
如果您提供更多关于用例的详细信息,我将能够更多地讨论您可以使用的方法。
发布于 2020-02-19 12:23:58
//映射(嵌套类别)
mapping dynamic: false do
indexes :created_at, type: 'date'
indexes :categories, type: 'nested' do
indexes :name, type: :text, analyzer: :english
end
end
// json
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),用于按类别搜索项目
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
https://stackoverflow.com/questions/60296524
复制相似问题