轮胎老板Karmi发布的问题的答案如下:
假设我们有一个 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!', ...
在某些情况下,为每个用户/帐户设置一个单独的索引是完美的——但在您拥有数万或数十万个索引(或更多)的情况下绝对不是很好。在这种情况下,拥有索引别名并正确设置过滤器和路由会表现得更好。我们将不基于租户身份,而是基于时间对数据进行切片。
让我们看看第二种情况,从一个高度简化的 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 年 7 月 12 日星期四写这篇文章)。下周的索引就在那里,等待中——到时候,后台作业(cron、Resque worker、自定义脚本……)将更新别名。在轮胎集成测试套件的“滑动窗口”场景中有一个漂亮的别名示例。
我们现在不看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,直接在相关索引中搜索该账号:“basic”或“pro”。
如果该帐户没有订阅——他可能是“访问者”类型——我们将搜索定向到articles_shared 别名。使用界面和以前一样简单,例如。在 ArticlesController 中:
@account = Account.find( remember_token_or_something_like_that )
@articles = @account.articles.search { query { ... } }
# ...
在这种情况下,我们没有使用 Article 类作为索引的网关;我们有一个单独的索引组件,一个 Sinatra 应用程序,作为 elasticsearch Bulk API 的轻代理,提供 HTTP 身份验证、文档验证(强制执行规则,例如所需的属性或作为 UTC 传递的日期),并使用裸 Tire::Index#import和 Tire::Index#store API。
这些 API 与 article_currentindex 别名对话,该别名通过所述后台进程定期更新到当前周。通过这种方式,我们解耦了在应用程序的单独组件中设置索引名称的所有逻辑,因此我们不需要访问索引代理中的 Article 或 Account 类(它运行在单独的服务器上),或任何应用程序的组成部分。无论哪个组件正在索引,都针对articles_current 别名进行索引;无论哪个组件正在搜索,搜索对特定组件有意义的任何别名或索引。