データベース
Apache Solr
概要
Apache Solrは、Apache Luceneをベースとした高性能なオープンソース検索プラットフォームです。エンタープライズ級の全文検索、ファセット検索、分散検索機能を提供し、大規模なWebサイトや企業アプリケーションで広く利用されています。
詳細
主要特徴
- Luceneベース: Apache Luceneの強力な検索機能を基盤とした高性能検索エンジン
- SolrCloud: Zookeeperを利用した分散アーキテクチャによる水平スケーリング
- 豊富な検索機能: 全文検索、ファセット検索、近接検索、ファジー検索、範囲検索
- マルチフォーマット対応: JSON、XML、CSV、PDF、Wordなど多様なドキュメント形式をサポート
- リアルタイムインデックス: 準リアルタイムでのドキュメント更新とインデックス作成
- 機械学習統合: Learning to Rank(LTR)、分類、クラスタリング機能
- ベクトル検索: 密なベクトルフィールドによるセマンティック検索
アーキテクチャ
Solrは以下の主要コンポーネントで構成されています:
- Solrコア: 検索インデックスと設定を管理する基本単位
- スキーマ: フィールド定義、分析器、インデックス設定を含む構造定義
- SolrCloud: Apache Zookeeperによるクラスター管理とノード間調整
- リクエストハンドラー: 検索、更新、管理API呼び出しの処理
- 分析器チェーン: テキスト処理のためのトークナイザーとフィルターの組み合わせ
メリット・デメリット
メリット
- 豊富な全文検索機能: ハイライト、ファセット、スペルチェック、オートコンプリート機能
- 優れた拡張性: SolrCloudによる水平スケーリングと高可用性
- エンタープライズ対応: セキュリティ、監視、管理機能が充実
- 真のオープンソース: Apache License 2.0による完全にオープンなライセンス
- 成熟したエコシステム: 豊富なプラグイン、ツール、コミュニティサポート
- スキーマレス機能: 動的フィールド定義による柔軟なデータ構造対応
- 多言語対応: 50以上の言語に対応した分析器とステマー
デメリット
- 設定の複雑さ: 初期設定と最適化には深い知識が必要
- メモリ消費: 大規模データセットでは高いメモリ使用量
- 学習コスト: XMLベースの設定ファイルとLucene知識が必要
- リアルタイム性: 完全なリアルタイム更新には制限
- JSONクエリサポート: JSONベースのクエリAPIは後発機能
- 開発者体験: ElasticsearchのREST APIと比較して複雑
主要リンク
書き方の例
インストール・セットアップ
# Solrの起動(techproductsサンプル)
bin/solr start -e techproducts
# 新しいコアの作成
bin/solr create -c mycore
# SolrCloudモードでの起動
bin/solr start -c -p 8983
基本操作(インデックス作成・検索)
# ドキュメントの追加(JSON)
curl -X POST "http://localhost:8983/solr/techproducts/update?commit=true" \
-H "Content-Type: application/json" \
-d '[
{
"id": "doc1",
"title": "Apache Solr検索エンジン",
"content": "高性能な全文検索機能を提供"
}
]'
# 基本検索
curl "http://localhost:8983/solr/techproducts/select?q=*:*"
# 特定フィールドでの検索
curl "http://localhost:8983/solr/techproducts/select?q=title:Apache"
スキーマ設計
<!-- schema.xml - フィールド定義 -->
<schema name="example" version="1.5">
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false"/>
<field name="title" type="text_general" indexed="true" stored="true"/>
<field name="content" type="text_general" indexed="true" stored="true"/>
<field name="category" type="string" indexed="true" stored="true" multiValued="true"/>
<!-- 動的フィールド(スキーマレス) -->
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<uniqueKey>id</uniqueKey>
</schema>
ファセット検索
# カテゴリ別ファセット検索
curl "http://localhost:8983/solr/techproducts/select?q=*:*&facet=true&facet.field=category"
# 範囲ファセット
curl "http://localhost:8983/solr/techproducts/select?q=*:*&facet=true&facet.range=price&facet.range.start=0&facet.range.end=1000&facet.range.gap=100"
# 複数条件ファセット
curl "http://localhost:8983/solr/techproducts/select?q=*:*&facet=true&facet.field=category&facet.field=brand&fq=category:electronics"
実用例
// JavaScriptでのSolr検索(Solrクライアント使用)
const solr = require('solr-client');
const client = solr.createClient();
// 検索実行
client.search('category:books AND author:村上春樹', {
facet: true,
'facet.field': ['genre', 'publisher'],
start: 0,
rows: 10,
sort: 'score desc'
}, function(err, obj) {
if (err) {
console.log(err);
} else {
console.log(obj.response.docs);
console.log(obj.facet_counts);
}
});
ベストプラクティス
<!-- solrconfig.xml - パフォーマンス最適化 -->
<config>
<!-- キャッシュ設定 -->
<query>
<filterCache class="solr.search.CaffeineCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<queryResultCache class="solr.search.CaffeineCache"
size="512"
initialSize="512"
autowarmCount="0"/>
</query>
<!-- 自動コミット設定 -->
<updateHandler class="solr.DirectUpdateHandler2">
<autoCommit>
<maxTime>30000</maxTime>
<openSearcher>false</openSearcher>
</autoCommit>
<autoSoftCommit>
<maxTime>1000</maxTime>
</autoSoftCommit>
</updateHandler>
<!-- Learning to Rank設定 -->
<transformer name="features" class="org.apache.solr.ltr.response.transform.LTRFeatureLoggerTransformerFactory">
<str name="fvCacheName">QUERY_DOC_FV</str>
</transformer>
</config>