この質問は、Github issue 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!', ...
ユーザー/アカウントごとに個別のインデックスを持つことは、特定のケースでは完璧に機能しますが、数万または数十万 (またはそれ以上) のインデックスがある場合には、うまくいきません。この場合、適切に設定されたフィルターとルーティングを使用してインデックス エイリアスを使用すると、パフォーマンスが大幅に向上します。テナント ID ではなく、時間に基づいてデータをスライスします。
http://localhost:9200/_aliases?pretty
非常に単純化された curl出力から始めて、2 番目のシナリオを見てみましょう。
{
"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" : {
}
}
}
週に 1 つずつ、3 つのインデックスがあることがわかります。article_plan_pro と article_plan_basic という 2 つの類似したエイリアスがあることがわかります。明らかに、「pro」サブスクリプションのアカウントは 2 週間前を検索できますが、「basic」サブスクリプションのアカウントは今週しか検索できません。
また、articles_current エイリアスが現在の週を指していることにも注意してください (これを書いているのは 2012 年 7 月 12 日木曜日です)。来週のインデックスはちょうどそこにあり、配置して待っています。時が来れば、バックグラウンド ジョブ (cron、Resque ワーカー、カスタム スクリプトなど) がエイリアスを更新します。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 を取得し、このアカウントの検索を関連するインデックス (「basic」または「pro」) に向けます。
アカウントがサブスクリプションを持っていない場合 (彼はおそらく「訪問者」タイプです)、検索を article_shared エイリアスに向けます。インターフェイスの使用は以前と同じくらい簡単です。ArticlesController:
@account = Account.find( remember_token_or_something_like_that )
@articles = @account.articles.search { query { ... } }
# ...
この場合、インデックス作成のゲートウェイとして Article クラスを使用していません。別のインデックス作成コンポーネント、elasticsearch Bulk API へのライト プロキシとして機能する Sinatra アプリケーションがあり、HTTP 認証、ドキュメント検証 (必要なプロパティや UTC として渡された日付などのルールを適用) を提供し、裸の Tire::Index#import を使用します。および Tire::Index#store API。
これらの API は、上記のバックグラウンド プロセスで現在の週に定期的に更新される article_currentindex エイリアスと通信します。このようにして、アプリケーションの個別のコンポーネントでインデックス名を設定するためのすべてのロジックを切り離したので、インデックス プロキシ (別のサーバーで実行されます) の Article または Account クラスへのアクセスは必要ありません。アプリケーションのコンポーネント。どのコンポーネントがインデックスを作成していても、articles_current エイリアスに対してインデックスを作成します。どのコンポーネントが検索されていても、特定のコンポーネントにとって意味のあるエイリアスまたはインデックスに対して検索します。