$30 off During Our Annual Pro Sale. View Details »

Amazon Neptuneで始めてみるグラフDB -OpenSearchによるグラフの全文検索-

Amazon Neptuneで始めてみるグラフDB -OpenSearchによるグラフの全文検索-

Satoshi Kaneyasu

October 20, 2024
Tweet

More Decks by Satoshi Kaneyasu

Other Decks in Programming

Transcript

  1. 2 自己紹介 氏名:兼安 聡 所属:株式会社サーバーワークス アプリケーションサービス部 在住:広島(フルリモート) 担当:DevOps、PM、SM 2024 Japan

    AWS Top Engineers (Database) 2024 Japan AWS All Certifications Engineers 認定スクラムマスター X:@satoshi256kbyte 去年よく触ってたDBはAmazon Timestream 今年はAmazon Neptuneをよく触ってます
  2. 目次 • グラフDBとは • Amazon Neptuneのデータを操作する方法 • Amazon Neptuneと全文検索 •

    (独断)グラフDBのメリット 業務で使っていますが、自分たち以外で使ってる人を見たことがないので、 使用方法の紹介とメリットはこれはなんじゃないかというのをお話ししま す。
  3. 6 グラフのモデルとクエリ言語 モデル クエリ言語 構造 プロパティグラフ • Gremlin (Apache TinkerPop)

    • Cypher (Neo4j) • ノード(頂点)とエッジ(辺)で構成 • ノードとエッジに任意のプロパティを持つ • ノード: エンティティやオブジェクト • エッジ: ノード間の関係 RDF • SPARQL • トリプル形式(主語、述語、目的語) • 主語: リソースやエンティティ • 述語: 関係やプロパティ • 目的語: 関係の相手やプロパティの値
  4. 7 グラフのモデルとクエリ言語 モデル クエリ言語 構造 プロパティグラフ • Gremlin (Apache TinkerPop)

    • Cypher (Neo4j) • ノード(頂点)とエッジ(辺)で構成 • ノードとエッジに任意のプロパティを持つ • ノード: エンティティやオブジェクト • エッジ: ノード間の関係 RDF • SPARQL • トリプル形式(主語、述語、目的語) • 主語: リソースやエンティティ • 述語: 関係やプロパティ • 目的語: 関係の相手やプロパティの値
  5. 9 グラフのモデルとクエリ言語 Pythonのサンプルコード Gremlinはプロパティグラフを操作する言語です SQLとは全く違う記法です 癖のある記法ではあります 左記のコードの特徴は、データを登録するにあたり、 DDLに相当するものがないことです。 グラフDBはスキーマレスなのでどんどんとデータを追 加することができます。

    繋がりのデータはいろんなタイプのデータがどんどん と追加されるのを想定しているので、柔軟性に長けて います。 〜省略〜 port = 8182 server = Neptuneのエンドポイント' endpoint = f'wss://{server}:{port}/gremlin' graph = Graph() connection = None try: connection = DriverRemoteConnection(endpoint, 'g', transport_factory=lambda: AiohttpTransport(call_from_event_loop=True)) g = graph.traversal().withRemote(connection) g.addV('service').property(T.id, '1').property('name', 'Neptune').iterate() g.addV('graph_type').property(T.id, '4').property('name', 'Property Graph').iterate() g.addV('query_language').property(T.id, '5').property('name', 'Gremlin').iterate() g.addV('query_language').property(T.id, '6').property('name', 'Cypher').iterate() g.addV('graph_type').property(T.id, '7').property('name', 'RDF Graph').iterate() g.addV('query_language').property(T.id, '8').property('name', 'SPARQL').iterate() 〜省略〜 g.V('1').addE('Graph Type').to(__.V('4')).iterate() g.V('4').addE('Query Language').to(__.V('5')).iterate() g.V('4').addE('Query Language').to(__.V('6')).iterate() g.V('1').addE('Graph Type').to(__.V('7')).iterate() g.V('7').addE('Query Language').to(__.V('8')).iterate() 〜省略〜 result = g.V().limit(25).bothE() print(result) finally: if connection is not None: connection.close() ノード(頂点)の登録 エッジの登録
  6. 13 Amazon Neptuneを操作するツール グラフDBを操作するツールとしては Tom Sawyer Graph Database Browserがあります。 これはphpMyAdminのようにブラウザでクエリが実行で

    きるツールです。 ローカルPCで動くツールやプログラムでNeptuneに繋ぐ ことはできるにはできます。 ただし、RDSと異なりパブリックアクセスがまだ実装され てない(2024年10月時点)ので、踏み台サーバーが必要 になります。
  7. 14 Tom Sawyer Graph Database Browserのイメージ g.V().has('name', 'Full-Text Search') .outE().as('edges1')

    // Full-Text Searchから出るエッジ .inV().as('nodes1') // 接続されているノード .outE().as('edges2') // さらに次のエッジ .inV().as('nodes2') // 次の段階のノード .select('edges1', 'nodes1', 'edges2', 'nodes2') この部分だけ抽出
  8. 17 グラフDBの全文検索 セットアップ時のポイント① このソリューション、自動で作成されて便利ではあるのですが、注意ポイントがあります。 NeptuneはVPCの中にいないといけない NeptuneはNeptune Streamを有効化しないといけない これは、パラメータグループで変更&再起動が必要 OpenSearch サービスドメインを事前に作成しておく必要がある

    OpenSearch サービスドメインは推奨設定に従って作るとIPv6を求められるので、VPCとサブネット の設定を変えるかIPv4モードに変えないといけない 推奨設定に従って作るとIAM認証になるので、Neptune側もそれに合わせるか、解除する必要がある OpenSearch用のセキュリティグループを作り、Neptuneのセキュリティグループに通しておく必要 がある リソースポリシーのデフォルトが全てDeny、これをAllowにしないと連携が成功しない (これはすごいハマりました・・・)
  9. 18 グラフDBの全文検索 セットアップ時のポイント② CloudFormationテンプレートのパラメータにも注意ポイントがあります パラメータ:List of Security Group Ids The

    Security groups associated with the Neptune Stream Cluster and Neptune Target Cluster. ここで指定したセキュリティグループが連携を実行するLambdaに付与される 原文をそのまま受け止めて、Neptuneが属するセキュリティグループと捉えると適切でない可能性が ある パラメータ:List of Route Table Ids Comma Delimited list of Route table ids associated with the Subnets. For Example: rtb- a12345,rtba7863k1. Optional parameter - Only needed when creating DynamoDB VPC Endpoint. ここで指定したルートテーブルに、LambdaがDynamoDBと通信するためのVPCエンドポイントが繋 がる。従って、これも上と同じようにNeptuneが属するサブネットと捉えると適切でない可能性があ る
  10. 19 グラフDBの全文検索 クエリのサンプル opensearch_endpoint = 'https://vpc-graphdb-opensearch-domain2-irj4z6yxd23cofmombf5zkam7q.ap-northeast- 1.es.amazonaws.com' try: connection =

    DriverRemoteConnection(endpoint, 'g', transport_factory=lambda: AiohttpTransport(call_from_event_loop=True)) g = graph.traversal().withRemote(connection) \ .withSideEffect('Neptune#fts.endpoint', opensearch_endpoint) # Elasticsearch endpointの設定 # 'policy' に近い名前を持つ要素を検索するクエリ result = g.V().hasLabel('key_checkpoint') \ .has('name', 'Neptune#fts policy~') \ .elementMap() \ .toList() # 検索結果をリストとして取得 df = pd.DataFrame(result) # 結果を表示 print(df) finally: if connection is not None: connection.close()
  11. 23 今時の調べる手段 インターネット検索 鉄板 キーワードが思いつかないと検索できない 生成AI 未経験者、初心者に優しい 冗長 正解に辿り着くまでに何度もやり取りする必要がある グラフDB

    繋がりが見えることで、自分にない気づきやヒントを得やすい わかる人にしかわからない、初心者よりちょっと先ぐらいの人向け
  12. 30 Appendix ➢参考ブログ ➢Amazon Neptuneで始める初めてのグラフDB① Neptuneクラスターと Notebookの作成 ➢Amazon Neptuneで始める初めてのグラフDB② Gremlinを用いたグラフデー

    タの基本操作 ➢Amazon Neptuneで始める初めてのグラフDB③ Amazon NeptuneとTom Sawyer Graph Database Browserとの接続 ➢Amazon Neptuneで始める初めてのグラフDB④ G.V()を用いてローカル端末 からAmazon Neptuneに接続する ➢Amazon Neptuneで始める初めてのグラフDB⑤ Amazon OpenSearch Serviceと連携した全文検索