ruby-on-rails - 单索引多类型-通过轮胎进行Elasticsearch分度

标签 ruby-on-rails elasticsearch ruby-on-rails-2 tire

在我的 Multi-Tenancy 应用程序(基于每个帐户的用户数的帐户)中,当更改用户文档时,如何更新特定帐户的索引。

我为每个帐户都有一个单独的索引,其中指定了每个模型的映射(用户和注释-只是示例实际应用程序具有许多模型)。在这种情况下,如果对用户模型或注释模型进行了任何更改,则必须更新为相关帐户创建的索引。这可能吗?如果可以,请告诉我。

我猜这是我指定情况下映射的方式。如果我错了纠正我。

帐户模型:

include Tire::Model::Search

Tire.index('account_1') do
  create(
    :mappings => {
      :user => {
        :properties => {
          :name => { :type => :string, :boost => 10 },
          :company_name => { :type => :string, :boost => 5 }
        }
      },
      :comments => {
        :properties => {
          :description => { :type => :string, :boost => 5 }
        }
      }
    }
  )
end

使用两个帐户索引映射正确创建了索引。但是,当映射中指定的任何模型发生更改时,我都看不到更新索引的方法。

每当添加新用户或更新用户时,都必须更新为相应帐户创建的索引。

最佳答案

这个问题来自Github问题Multiple model single index approach。在这里交叉张贴答案。

假设我们有一个Account类,并且我们处理商品实体。

在这种情况下,我们的Account类将具有以下内容:

class Account
  #...

  # Set index name based on account ID
  #
  def articles
      Article.index_name "articles-#{self.id}"
      Article
  end
end

因此,只要我们需要访问特定帐户的文章(用于搜索或建立索引),我们都可以简单地执行以下操作:
@account = Account.find( remember_token_or_something_like_that )

# Instead of `Article.search(...)`:
@account.articles.search { query { string 'something interesting' } }

# Instead of `Article.create(...)`:
@account.articles.create id: 'abc123', title: 'Another interesting article!', ...

在某些情况下,每个用户/帐户拥有一个单独的索引非常合适-但在您拥有成千上万个索引(或更多)的情况下,绝对不行。在这种情况下,具有索引别名以及正确设置的筛选器和路由会更好。我们不会根据租户身份对数据进行 slice ,而是根据时间对数据进行 slice 。

让我们看第二种情况,首先是大大简化的curl http://localhost:9200/_aliases?pretty输出:
{
  "articles_2012-07-02" : {
    "aliases" : {
      "articles_plan_pro" : {
      }
    }
  },
  "articles_2012-07-09" : {
    "aliases" : {
      "articles_current" : {
      },
      "articles_shared" : {
      },
      "articles_plan_basic" : {
      },
      "articles_plan_pro" : {
      }
    }
  },
  "articles_2012-07-16" : {
    "aliases" : {
    }
  }
}

您可以看到我们有三个索引,每周一个。您可以看到有两个类似的别名:articles_plan_pro和articles_plan_basic-显然,具有“pro”订阅的帐户可以在两周后搜索,但是具有“basic”订阅的帐户只能在本周搜索。

还要注意,articles_current别名指向,例如,本周(我在2012年4月12日星期四撰写)。下周的索引就在这里,等待等待-到时,后台作业(cron,Resque worker,自定义脚本等)将更新别名。 Tire集成测试套件中的“滑动窗口”场景中有一个带有别名的漂亮示例。

让我们现在不看看articles_shared别名,让我们看看在此设置下可以使用的技巧:
class Account
  # ...

  # Set index name based on account subscription
  #
  def articles
    if plan_code = self.subscription && self.subscription.plan_code
      Article.index_name "articles_plan_#{plan_code}"
    else
      Article.index_name "articles_shared"
    end
    return Article
  end
end

再次,我们为Article类设置一个index_name,其中包含我们的文档。当当前帐户具有有效的订阅时,我们将从订阅中获取plan_code,然后直接在相关索引中搜索该帐户:“基本”或“专业”。

如果该帐户没有订阅-他可能是“访客”类型-,我们会将搜索定向到articles_shared别名。使用界面和以前一样简单,例如。在ArticlesController中:
@account  = Account.find( remember_token_or_something_like_that )
@articles = @account.articles.search { query { ... } }
# ...

在这种情况下,我们不使用Article类作为索引的网关;我们有一个单独的索引编制组件,一个Sinatra应用程序,充当Elasticsearch Bulk API的轻型代理,提供HTTP身份验证,文档验证(强制执行规则,如所需属性或以UTC形式传递的日期),并使用裸Tyre::Index#import和Tire::Index#store API。

这些API会与articles_currentindex别名通信,该别名会通过所述后台进程定期更新到当前星期。这样,我们就取消了在单独的应用程序组件中设置索引名称的所有逻辑,因此我们不需要访问索引代理(它在单独的服务器上运行)中的Article或Account类。应用程序的组件。无论索引的哪个组件,都针对articles_current别名进行索引;无论要搜索哪个组件,都将搜索对该特定组件有意义的任何别名或索引。

关于ruby-on-rails - 单索引多类型-通过轮胎进行Elasticsearch分度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13743334/

相关文章:

ruby-on-rails - 向 Rails 中的 link_to 方法添加 onclick 选项?

ruby-on-rails - 在 mongoid-gridfs 上使用 Rails 进行 Cucumber 测试时出现“ERROR Mongo::OperationFailure”

elasticsearch - ElasticSearch 7.6.3 Java HighLevel Rest Client:跨多个字段自动建议-如何实现

ruby-on-rails - 升级rails 2.3后在集成测试中设置多个cookie会导致NoMethodError

mysql - 记录对数据库的更改

ruby-on-rails - 单击 html 按钮时如何执行 Rails 操作?

ruby-on-rails - Heroku 部署和解释 Heroku 日志的问题

elasticsearch - elastic4s 2.3.0是否支持按查询Api更新?

node.js - match_phrase 不适用于 Elasticsearch 中的同义词标记过滤器(类型扩展)

ruby-on-rails - 没有 accepts_nested_attributes_for 的嵌套 rails 形式