エキサイト株式会社の武藤です。
エキサイトホールディングス Advent Calendar 2021の18日目の記事です。
今回は、Spring Boot プロジェクトでSolrJを使ってSolr検索を実装する手順について説明します。
SolrJ
SolrのJava用のAPIです。 solr.apache.org
Spring Bootには、Solr用のSpring Dataがありますが、新規プロジェクトへの利用は非推奨です。
This project is about to move to the Spring Attic and is not recommended for new projects. The last Release (4.3.0) will, as part of the spring data release 2020.0, see patch updates till mid 2022.
そういった経緯もあり、今回はSolrJを採用しました。
実装
build.gradle に下記の行を追加します。
implementation "org.apache.solr:solr-solrj:x.xx.x"
@Field
でスキーマのフィールド名からJavaのプロパティーへの変換を設定します。
@Data public class BookSolrModel { @Field("book_id") private String bookId; @Field private String name; @Field private String description; }
次に、リクエストからレスポンスの取得です。Spring BootのRepository層での実装例です。
SolrQueryをインスタンス化し、クエリーをセットします。
Solrから取得したBookSolrModelをドメインモデルにマッピングしています。
HttpSolrClient.query()はThrowableなので、例外ハンドリングをしています。
@Repository @RequiredArgsConstructor public class BookRepositoryImpl implements BookRepository { private final HttpSolrClient httpSolrClient; @Override public List<BookModel> getBookList(String bookId) { try { final SolrQuery query = new SolrQuery(); query .setQuery("book_id:" + bookId) .setStart(0) .setRows(1); final QueryResponse response = httpSolrClient.query(query); final List<BookSolrModel> bookSolrModelList = httpSolrClient .getBinder() .getBeans(BookSolrModel.class, response.getResults()); return bookSolrModelList .stream() .map(bookSolrModel -> new BookModel() .setBookId(bookSolrModel.getBookId()) .setName(bookSolrModel.getName()) .setDescription(bookSolrModel.getDescription()) ) .collect(Collectors.toList()); } catch (SolrServerException | IOException e) { return List.of(); } } }
HttpSolrClientは @Bean
によりDIコンテナに登録することで、他のRepositoryでもインスタンスを使い回せるようにしています。
Solrのホストはapplication.yml で定義しておき、 @Value
で呼び出します。これにより環境の差異をコードに記載しなくて済みます。
@Configuration public class SolrConfig { @Value("${solr.host}") private String solrHost; @Bean public HttpSolrClient httpSolrClient() { return new HttpSolrClient.Builder(solrHost).build(); } }
類似要素検索
MoreLikeThisを使った類似検索の例です。
final SolrQuery query = new SolrQuery(); query .setQuery("book_id:" + bookId) .setStart(0) .setRows(1) .setMoreLikeThis(true) .setMoreLikeThisFields("name") .setMoreLikeThisCount(3); final QueryResponse response = httpSolrClient.query(query); final List<BookSolrModel> bookSolrModelList = httpSolrClient .getBinder() .getBeans(BookSolrModel.class, response.getMoreLikeThis().get(bookId));
最後に
簡単にですが、Spring BootプロジェクトでのSolrJの使い方について説明しました。 他の言語で提供されているSolr APIと大きな差はなく、使いやすいものでした。 参考になれば幸いです。
エキサイトでは、エンジニア募集を随時行っております。 www.wantedly.com
引き続きエキサイトホールディングスのアドベントカレンダーをお楽しみいただければ幸いです。 qiita.com