少し前に、私はプロジェクトの簡単な検索サービスを構築することを計画していました。ビジネスデータベースMongoDBはテキスト検索サポートを提供しますが、キーワードを使用して多数のドキュメントを配置する必要がある場合、ESは検索エンジンとして明らかに適しています(ただし、私たちのほとんどはElkの分析と視覚化機能を以前に使用していました)。 ElasticSearchはLuceneに基づいて構築されており、非常に高速なクエリとリッチクエリ構文をサポートし、時には軽量のNOSQLとして機能します。ただし、複雑なクエリと集約操作を複雑にする機能はそれほど強くありません。
この記事では、簡単な検索サービスを構築する方法については言及していませんが、約1週間の勤務時間中に遭遇したいくつかの落とし穴を記録します。 。
なぜelasticsearch 5.xを選ぶのですか?
新しいサービスには歴史的な負担はなく、理論的には最新の6.xを使用する必要があります。ただし、Spring-Data-Elasticsearchは5.xのみをサポートしており、時間が厳しい場合でも、APIの層を直接カプセル化することは困難です。また、以前のバージョンのElk's Stuffが混乱していたため、2.xから5.xに移動する以外に選択肢がなかったためです。 5.xと2.xの差を照会します。簡単に言えば、ディスクスペース-50%、インデックス時間-50%、クエリパフォーマンス +25%です。
Spring-Data-Elasticsearchを3.0.7にアップグレードする必要があるため、Springを2.xにアップグレードする必要があります。
DockerインストールESは、デフォルトでX-Pathプラグインをインストールします
Spring-DataはES5.xをサポートしていますが、その機能はそれほど完全ではありません。したがって、X-Pathプラグインがインストールされている場合、org.elasticsearch.client:x-pack-transport:5.5.0を導入する必要があります。バージョンはESバージョンと同じである必要があり、次のようにTransportClientを実装できます
@componentPublic Class Esconfig {@Bean Public TransportClient TransportClient()Throws nown ofnownhostexception {TransportClientクライアント= new prebuiltxpacktransportclient(settings.builder().put( "cluster.name"、 "docker-cluster").put( "xpack.security.user" .addtransportaddress(new inetsocketTransportAddress(inetAddress.getByname( "0.0.0.0")、9300));クライアントを返します。 }}これは、X-Pathプラグインに対処するためにDockerに行きたくないため、より高速なソリューションでもあります。それが不要な場合は、当面の間、ES自体のいくつかのものに触れる必要はありません。
MQはメッセージのクラス情報を保存し、脱介入を失敗させます
タイトルのrabbitmqは、メッセージキューとして使用されているため、言及されていません。データが変更されると、メッセージIDがMQにスローされ、検索サービスの消費者が消費されます。
問題は、メッセージがMQにスローされると、独自のオブジェクトにカプセル化され、rabbittemplate.receiveandConvertがオブジェクトパッケージ情報を運ぶために失敗することです。絶望的に、消費者はキュー内のメッセージバイトを直接取得し、objectMapper.readValueメソッドを使用してJSONフォームをオブジェクトに変換することができます。
Gradle構成は-dloader.mainを使用してスタートアップ機能を指定できます
まさに、MQが導入されたためです。検索サービスが消費者を開始する必要があることです。この方法は、Webサービスを開始しないアプリケーションを実装し、次のようにSimpleMessagElistenerContainerとMessageListenerAdapterを構成することです。
@Bean SimpleMessagElistenerContainerコンテナ(ConnectionFactory ConnectionFactory、MessageListenerAdapterリスナーアダプター、MQConfigプロパティ){SimpleMessagElistenerContainer Container = new SimpleMessagElistenerContainer(); container.setConnectionFactory(ConnectionFactory); container.setqueuenames(properties.getqueuename()); container.setmessageListener(listenerAdapter);返品コンテナ。 } @Bean MessageListenerAdapter ristenerAdapter(){MessageListenerAdapter rirederDapter = new MessageListenerAdapter(ItemConsumer、 "Canume"); RETURNERADAPTER; }問題は、Gradle構成のときに、指定された-dloader.mainでJARパッケージを構築してスタートアップアプリケーションを指定するために長い間検索したことです。解決策は次のとおりです。
xxx.gradleファイルを追加します
bootjar {manifest {actributes 'main-class': 'org.springframework.boot.loader.propertieslauncher'}}}Springboot 1.5.9プロジェクトでは、スタートアップアプリケーションを指定し、追加する必要があります
springboot {layout = "zip"}効果があるかどうかを確認する方法は、構築後にJARパッケージを直接解凍し、xxx(プロジェクト名)/meta-info/manifest.mfで確認することです。
メインクラス:org.springframework.boot.loader.propertieslauncher
次に、正しい場合
メインクラス:org.springframework.boot.loader.jarlauncher
ファイルのスタートクラスは引き続き開始されます
ESはインデックスのマッピングを変更できません
ESのテキスト検索機能を使用するだけであるため、「デスク」の検索など、実際のアプリケーションには多くの不満足な検索結果があり、「コンピューターデスク/オフィスデスク」やその他のXXテーブルなどのコンテンツを検索することは不可能です。このように多くの場合があります。したがって、同義語辞書が追加され、IK_SMART Word Segmenterは単語セグメンテーションを必要とするフィールドでは使用されていないため、一部のフィールドのマッピングを変更する必要があります。
// Analyzerは独自の単語セグメルター@field(type = fieldtype.text、index = true、analyzer = "synconym")private string descriptionです。
ES 'マッピングを変更できないため、新しいマッピングを手動でのみ作成してから、Reindexメソッドを使用してデータを埋めることができます(ES5.xにはReindex APIが付属しています)。エイリアスを介してオンラインの方法があります。一部の変更シナリオでは、アプリケーションを再起動/展開せずにマッピングをスムーズに変更できます。詳細をクエリして理解できます。
上記は、検索サービスによって触れられたほぼ落とし穴です。それらのいくつかは、解決するために多くの時間とエネルギーを消費しています。このリストの参照値になることを願っています。将来的には、検索サービスにいくつかの最適化が行われ、引き続きゆっくりと更新されます。また、誰もがwulin.comをもっとサポートすることを願っています。