初心者向けのフレックス検索を開始(NodeJSを使用)

8606 ワード

🔎 フレックスサーチとは?


オープンソース検索エンジン

🗒 ノード、クラスタ、インデックス


ノードは検索エンジンサーバを表します.
ノードの名前はuuidを一意の名前とし、他の名前に変更できますが、一意の値を持つように設定してください.
クラスタは上のノードの集合です.
単一のデータはドキュメンタリーで、これらのデータの集合はインデックスです.インデックスはインデックスとも呼ばれます.これらのインデックスのセットはノードです.
グリッドはインデックスの単位です.グリッドの存在は、インデックス内のデータが大きくなったり、ワークロードが増加したりしないように、インデックスにデータを分散するためです.
軽く理解したいなら、以下のようにします.
ドキュメント(データ)

🛫 Install


Java、フレックス検索をインストールする必要があります.
次のリンクにアクセスしてjavaをダウンロードしてください.
https://www.java.com/ko/download/
次に、フレックス検索を受け入れる必要があります.(macベース)
homebrewでダウンロードすると便利です.
ログイン端末は以下のコマンドを入力すればよい.
//brew 업데이트를 먼저 진행해줍니다.
$brew update

//아래 명령어들을 사용해 elasticseach를 다운로드 합니다.
$brew install elastic/tap/kibana-full
$brew install elasticsearch-full
上記のインストールが完了したら、次のコマンドを実行します.
$elasticsearch
Elasticsearchは9200ポートで動作します.
http://127.0.0.1:9200/
アップリンクすると、基本的なクラスタ情報が表示されます.

9200ポートで正常な動作を確認した場合は、node jsサーバへの接続を確認します.
npmまたは糸で弾性検索パッケージを取り付けてください.
yarn add @elastic/elasticsearch
インストールが完了したら、ノードサーバに接続してみますか?
import { Client } from "@elastic/elasticsearch";

const client = new Client({
  node: "http://localhost:9200",
  maxRetries: 5,
  requestTimeout: 60000,
  sniffOnStart: true,
});

async function bootstrap() {
  try {
    client.ping();
    console.log("9200번 포트 연결");
  } catch (e) {
    console.log(e);
  }
}
bootstrap();
接続が成功すると、以下のようにconsole logが表示されます.

フレックス検索を開始せずに上のコードのみを実行すると、node jsを実行せずに次のようにエラーコードが解放されます.$elasticsearchは必ず端末で実行してください.

🔢 索引の作成


kibanaを使用するには、次のリンクを参照してください.JavaScriptしか使いませんでしたが、kibanaを使って簡単に操作する方法もありました.
https://needjarvis.tistory.com/546
次のコードを使用してインデックスを作成します.インデックス名はticketsによって作成されます.
  try {
    client.indices.create({
      index: "{인덱스 이름}",
    });
  } catch (error) {
    console.log(error);
  }
作成に成功すると、http://127.0.0.1:9200/{インデックス名}に次の画面が表示されます.

弾性調査データを挿入します.これを行うには、type、document、indexの概念が徐々に混同される可能性があります.理解しやすいように、次の内容を参照してください.
RDBMSElasticsearchDatabaseIndexTableTypeRowDocument
**Elastic 7.0からインデックスの概念とtypeの概念が同じになるので、インデックスごとに1つのタイプ**があります.

データINSERT


私はサーバーレンタルを利用していますが、MySQLとElasticSearch連動のlogstashは使用していません.
何か質問があれば、以下のブログを参考にしてください.詳しく説明する.
https://drhot552.github.io/web/Logstash-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-mysql%EC%99%80-ElasticSearch-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0/#logstash%EC%99%80-mysql%EC%99%80-elasticsearch-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0
csvファイルをフレキシブル検索データとして保存したので、以下のコードを使用しました.
上に作成したインデックスの下にデータを置けばいいです.
データの内容をdocumentに書けばいいです私の書いた記号や名前を机の上のコラム名に書けばいいです.
追加fs.readFileSyncは絶対パスでアクセスする必要があります.
import fs from "fs";

  const file = fs.readFileSync(
    "절대경로/파일이름.csv",
    "utf8"
  );
  const data = file.split("\r\n");
  for (let i = 1; i < data.length; i++) {
    const ticker = data[i].split(",");
    await client.index({
      index: "{인덱스 이름}",
      document: {
        symbol: ticker[0],
        name: ticker[1],
        country: ticker[6],
        sector: ticker[9],
        industry: ticker[10],
      },
    });
  }
次のリンクに接続して、データが完全に保存されていることを確認します.
http://127.0.0.1:9200/{インデックス名}

次にgetでデータの受信が良好かどうかを確認しましょう.
http://127.0.0.1:9200/{インデックス名}/search?q={クエリ}
下のように入ってくると検索がうまくいきます!ほほほ

🖨 Node jsでSearch APIにバインド


次に、クエリーを入力してnestjsコードを作成し、対応するデータを送信します.
フレックスサーチの接続を接続します.tsを作成するには、次のようにします.
// connection.ts
import { Client } from "@elastic/elasticsearch";

const client = new Client({
  node: "http://localhost:9200",
  maxRetries: 5,
  requestTimeout: 60000,
  sniffOnStart: true,
});

export default client;
apiサービスを処理するサービス.tsから上に接続されたクライアントをインポートします.
importのclientを使用して検索します.
//findings.service.ts
  async find(keyword): Promise<Findings[]> {
    const query = keyword;
    const elastic = client;
    try {
      const data = await elastic.search({
        index: "{인덱스 이름}",
        query: {
          match: {
            {칼럼명}: keyword,
          },
        },
      });
      //임시로 return 값은 query로 설정
      return query;
    } catch (error) {
      console.log(error);
    }
  }
コントローラが設定したurlに入り、データを受信すると、次のようにタイプobjectのデータに入ります.(私の場合、http://127.0.0.1:4000/tickers/search?keyword={クエリー}に設定されています.)
object
{
  took: 36,
  timed_out: false,
  _shards: { total: 1, successful: 1, skipped: 0, failed: 0 },
  hits: {
    total: { value: 104, relation: 'eq' },
    max_score: 4.499482,
    hits: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object]
    ]
  }
}
以下のように分析した.( https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/search_examples.html )
名前はtookElasticsearchが検索を実行するのに費やした時間(ミリ秒)timed out検索がタイムアウトしたかどうか、shard検索のshard数、検索に成功/失敗したshard数hits検索結果hitsを意味します.検索条件に一致するドキュメントの合計数がヒットしました.hits検索結果の実際の配列(プリファレンスは上位10ドキュメント)hits.sort結果のソートキー(スコアでソートした場合は表示されません)max scoreマッチングに成功したドキュメントで最も得点が高い
ヒッツの中のヒッツに近づく
data.hits.コンソールでhitsを撮影すると、次の形式で表示されます.
//예시
[
//...(중략)
{
    _index: 'tickers',
    _type: '_doc',
    _id: 'VFgSzH8B6Mx3vsBiOEzf',
    _score: 3.2218409,
    _source: {
      symbol: 'ALIN^A',
      name: 'Altera Infrastructure L.P. 7.25% Series A ',
      country: 'Bermuda',
      sector: '',
      industry: ''
    }
  }
]
これらの配列にobject形式で入力されるデータは、for文であってもよいし、forEachまたはmap形式のデータであってもよい.
//findings.service.ts

import client from "src/connection";

type findingDataType = {
  [key: string]: string[];
};

  async find(keyword): Promise<findingDataType[]> {
    const query = keyword;
    const elastic = client;
    try {
      const response = await elastic.search({
        index: "{인덱스 이름}",
        query: {
          match: {
            {칼럼명}: keyword,
          },
        },
      });
      const data = response.hits.hits.map((row) => {
        return {
          id: row._source["id"],
          name: row._source["{칼럼명}"],
        };
      });
      return data;
    } catch (error) {
      console.log(error);
    }
  }