mcpField
N
neo4j-kafka-skill

neo4j-kafka-skill

github.com/neo4j-contribデータ・データベース118782 回インストール1 週間前に更新
リポジトリ

neo4j-kafka-skill について

neo4j-kafka-skillは、Neo4j Connector for Kafkaを使う開発者向けの設定・トラブルシューティングガイドです。双方向のイベント連携、ネイティブCDCクエリ、信頼性設定、マネージドサービスの構成を扱います。

主な機能

  1. 01KafkaからNeo4jへのSink戦略
  2. 02Neo4jからKafkaへのSource戦略
  3. 03ネイティブCDCクエリとカーソル処理
  4. 04Exactly-onceとデッドレターキューの設定
  5. 05Schema Registryの設定ガイド

活用シーン

  1. 01KafkaイベントをNeo4jのグラフに書き込む
  2. 02Neo4jの変更をKafkaへストリーミングする
  3. 03KafkaなしでCDCイベントをクエリする
  4. 04Confluent Cloud Neo4j Sinkを構成する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/neo4j-contrib/neo4j-skills --skill neo4j-kafka-skill

インストール後、Claude Code で/neo4j-kafka-skillを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
references/
cdc-api.md
sink-config.md

詳細

Neo4j Kafka スキル

使用する場面

  • Kafka イベントを Neo4j に書き込む場合(シンクコネクター — Cypher、Pattern、CDC、CUD 戦略)
  • Neo4j の変更を Kafka トピックにストリーミングする場合(ソースコネクター — CDC またはクエリベース)
  • Kafka を使わずに Neo4j の変更イベントをネイティブにクエリする場合(db.cdc.query)
  • Confluent Cloud のマネージド Neo4j シンクコネクターを設定する場合
  • 型付き Kafka メッセージ向けにスキーマレジストリ(Avro/JSON Schema)を設定する場合
  • シンクで exactly-once セマンティクスまたはデッドレターキューを有効にする場合

使用しない場面

  • Cypher クエリの作成 → neo4j-cypher-skill
  • CSV/JSON ファイルの一括インポート → neo4j-import-skill
  • GDS アルゴリズム → neo4j-gds-skill
  • ライブアプリの書き込みパターン → neo4j-cypher-skill

選択表 — どのコネクター戦略を使うか?

ユースケース戦略
Kafka ペイロードをグラフにカスタム変換するシンク:Cypher
別の Neo4j CDC ソースをミラーリングするシンク:CDC(schema または source-id サブ戦略)
コードを書かずに Kafka JSON フィールドをグラフのノード/リレーションにマッピングするシンク:Pattern
事前フォーマット済みの CUD JSON メッセージを消費するシンク:CUD
すべての Neo4j の変更を Kafka にストリーミングする(リアルタイム)ソース:CDC(Neo4j 5.13+ EE/Aura BC/VDC)
特定のクエリ結果をスケジュールに従ってストリーミングするソース:Query
Kafka を使わず、プロセス内で CDC イベントを消費するネイティブ CDC API(db.cdc.query)

前提条件

  • Neo4j Connector for Kafka ≥ 5.5.2(neo4j.com/labs/kafka または Confluent Hub からダウンロード)— 5.5.2 はトピック単位ではなくパーティション単位で受信メッセージを処理します。5.5.1 では生成されるクエリに静的ラベルが強制されます
  • Kafka Connect ≥ 3.x または Confluent Platform ≥ 7.x
  • CDC ソース/シンクの場合:Neo4j 5.13+ Enterprise Edition、AuraDB Business Critical、または AuraDB VDC
  • クエリソースの場合:すべての Neo4j エディション
  • Java 11+

コア接続設定(すべてのコネクター)

{
  "neo4j.uri": "neo4j+s://your-instance.databases.neo4j.io:7687",
  "neo4j.authentication.type": "BASIC",
  "neo4j.authentication.basic.username": "neo4j",
  "neo4j.authentication.basic.password": "${file:/opt/secrets.properties:neo4j.password}",
  "neo4j.database": "neo4j"
}

認証タイプ:BASIC | BEARER | KERBEROS | CUSTOM | NONE

パスワードをハードコードしないでください — Kafka Connect のシークレットプロバイダー(${file:...} または ${env:...})を使用してください。


シンクコネクター

戦略 1 — Cypher

コネクターは自動的に UNWIND $events AS __value を先頭に追加します — __value を使って書き込みクエリを作成してください。

{
  "connector.class": "org.neo4j.connectors.kafka.sink.Neo4jConnector",
  "topics": "person-creates,person-updates",
  "neo4j.uri": "neo4j+s://...",
  "neo4j.authentication.type": "BASIC",
  "neo4j.authentication.basic.username": "neo4j",
  "neo4j.authentication.basic.password": "secret",
  "neo4j.cypher.topic.person-creates":
    "MERGE (p:Person {id: __value.id}) SET p += __value.properties",
  "neo4j.cypher.topic.person-updates":
    "MATCH (p:Person {id: __value.id}) SET p += __value.properties",
  "neo4j.cypher.bind-value-as": "__value",
  "neo4j.cypher.bind-key-as": "__key",
  "neo4j.cypher.bind-header-as": "__header"
}

MERGE パターン — 冪等なアップサート:

MERGE (p:Person {id: __value.id})
ON CREATE SET p.createdAt = datetime(), p += __value.properties
ON MATCH  SET p.updatedAt = datetime(), p += __value.properties
戦略 2 — Pattern

Cypher は不要です — パターン構文でメッセージフィールドをグラフにマッピングします。

{
  "neo4j.pattern.topic.users": "(:User{!userId, name, email})",
  "neo4j.pattern.topic.friendships":
    "(:User{!userId: from.userId})-[:KNOWS{since}]->(:User{!userId: to.userId})"
}

パターンのルール:

  • !prop = キープロパティ(MERGE に使用)
  • prop: field.path = ネストされたメッセージフィールドからマッピング
  • * = すべてのメッセージフィールドをマッピング
  • -prop = プロパティを除外(包含指定との併用不可)
戦略 3 — CDC(別の Neo4j をミラーリング)
{
  "neo4j.cdc.schema.topics": "neo4j-cdc-events"
}

または source-id トラッキングを使用します(elementId をプロパティとして保存):

{
  "neo4j.cdc.source-id.topics": "neo4j-cdc-events",
  "neo4j.cdc.source-id.label-name": "SourceEvent",
  "neo4j.cdc.source-id.property-name": "sourceId"
}
Exactly-Once セマンティクス(EOS)

必要条件:コネクター ≥ 5.3.0(Cypher/Pattern/CDC 戦略)、コネクター ≥ 5.3.1(CUD 戦略)、Kafka ブローカーの EOS サポート、および NODE KEY 制約。

ステップ 1 — 制約を作成します:

CREATE CONSTRAINT kafka_offset_key IF NOT EXISTS
FOR (n:__KafkaOffset)
REQUIRE (n.strategy, n.topic, n.partition) IS NODE KEY;

ステップ 2 — コネクター設定に追加します:

{
  "neo4j.eos-offset-label": "__KafkaOffset"
}

EOS を使用しない場合:コネクターは at-least-once を提供します — 冪等な Cypher(CREATE ではなく MERGE)を書いてください。

エラー処理/DLQ
{
  "errors.tolerance": "all",
  "errors.log.enable": "true",
  "errors.log.include.messages": "true",
  "errors.deadletterqueue.topic.name": "neo4j-dlq",
  "errors.deadletterqueue.context.headers.enable": "true",
  "errors.deadletterqueue.topic.replication.factor": "3"
}

errors.tolerance=none(デフォルト)— 最初のエラーで停止します。本番環境では all と DLQ を使用してください。


ソースコネクター

CDC ベースのソース(推奨、Neo4j 5.13+)
{
  "connector.class": "org.neo4j.connectors.kafka.source.Neo4jConnector",
  "neo4j.uri": "neo4j+s://...",
  "neo4j.authentication.type": "BASIC",
  "neo4j.authentication.basic.username": "neo4j",
  "neo4j.authentication.basic.password": "secret",
  "neo4j.source-strategy": "CDC",
  "neo4j.start-from": "NOW",
  "neo4j.cdc.poll-interval": "1s",
  "neo4j.cdc.poll-duration": "5s",
  "neo4j.cdc.topic.person-creates.patterns.0.pattern": "(:Person)",
  "neo4j.cdc.topic.person-creates.patterns.0.operation": "CREATE",
  "neo4j.cdc.topic.person-updates.patterns.0.pattern": "(:Person)",
  "neo4j.cdc.topic.person-updates.patterns.0.operation": "UPDATE",
  "neo4j.cdc.topic.person-deletes.patterns.0.pattern": "(:Person)",
  "neo4j.cdc.topic.person-deletes.patterns.0.operation": "DELETE"
}

neo4j.start-from のオプション:NOW | EARLIEST | 特定のカーソル文字列

1 つのトピックに複数のパターンを指定できます — 0、1、2... のインデックスを付けます:

{
  "neo4j.cdc.topic.all-changes.patterns.0.pattern": "(:Person)",
  "neo4j.cdc.topic.all-changes.patterns.1.pattern": "(:Organization)"
}

カーソルに関する警告:バックアップから DB を復元すると、CDC カーソルは無効になります。neo4j.start-from を再設定してください。

クエリベースのソース(レガシー/すべてのエディション)
{
  "neo4j.source-strategy": "QUERY",
  "neo4j.query": "MATCH (p:Person) WHERE p.updatedAt > $lastCheck RETURN p.id AS id, p.name AS name, p.updatedAt AS updatedAt",
  "neo4j.query.streaming-property": "updatedAt",
  "neo4j.query.topic": "person-changes",
  "neo4j.query.polling-interval": "5s",
  "neo4j.query.polling-duration": "10s"
}

$lastCheck はコネクターによって自動的に注入されます。neo4j.query.streaming-property はクエリの戻り値に含める必要があり、インデックスを付けることを推奨します。


ネイティブ CDC API(Kafka 不要)

必要条件:Neo4j 5.13+ Enterprise、AuraDB BC、または AuraDB VDC。

まず CDC を有効にします(セルフマネージド — neo4j.conf に設定):

db.cdc.enabled=true

Aura では、対象ティアでデフォルトで有効になっています。

カーソルの初期化
// Get cursor for "right now" — start tracking from this point forward
CALL db.cdc.current() YIELD id RETURN id AS cursor;

// Get earliest available cursor (replay from history start)
CALL db.cdc.earliest() YIELD id RETURN id AS cursor;

カーソルは排他的です。db.cdc.current() には、カーソルが指すトランザクションは含まれません。

クエリの変更
// All changes since cursor
CALL db.cdc.query($cursor, []) YIELD id, txId, seq, metadata, event
RETURN id, txId, seq, metadata, event
ORDER BY txId, seq;

フィルター適用済み — ラベルが Person のノードのみ、CREATE のみ:

CALL db.cdc.query($cursor, [
  {select: 'n', labels: ['Person'], operation: 'c'}
]) YIELD id, txId, seq, event
RETURN id, event.state.after.properties AS newProps
ORDER BY txId, seq;

フィルター適用済み — プロパティ変更の追跡を伴う、特定のリレーションシップタイプ:

CALL db.cdc.query($cursor, [
  {select: 'r', type: 'KNOWS', changesTo: ['since', 'strength']}
]) YIELD id, txId, seq, event
RETURN id, event.state.before AS before, event.state.after AS after;
セレクターのリファレンス
フィールド値適用対象
select'e'(すべて)、'n'(ノード)、'r'(リレーションシップ)両方
operation'c'(作成)、'u'(更新)、'd'(削除)両方
labels['Label1','Label2'](ノードはすべてを持つ必要があります)ノード
type'REL_TYPE'リレーションシップ
elementId特定の要素 ID 文字列両方
key{propName: value}(キー制約が必要です)両方
changesTo['prop1','prop2'](AND — すべてが変更される必要があります)両方
authenticatedUserユーザー名文字列両方
executingUserユーザー名文字列両方
txMetadata{key: value}両方
イベント構造
{
  id:       STRING,           // cursor for this event (use as next $cursor)
  txId:     INTEGER,          // transaction ID
  seq:      INTEGER,          // ordering within transaction
  metadata: {
    executingUser:     STRING,
    authenticatedUser: STRING,
    captureMode:       STRING,  // "DIFF" or "FULL"
    txStartTime:       DATETIME,
    txCommitTime:      DATETIME,
    txMetadata:        MAP
  },
  event: {
    elementId:  STRING,
    eventType:  STRING,         // "n" or "r"
    operation:  STRING,         // "c", "u", "d"
    labels:     [STRING],       // nodes only
    type:       STRING,         // relationships only
    keys:       MAP,
    state: {
      before: { properties: MAP },  // null on CREATE
      after:  { properties: MAP }   // null on DELETE
    }
  }
}
カーソルループパターン(Python)
from neo4j import GraphDatabase

driver = GraphDatabase.driver("neo4j+s://...", auth=("neo4j", "password"))

def poll_changes(cursor: str, selectors: list) -> tuple[list, str]:
    records, _, _ = driver.execute_query(
        "CALL db.cdc.query($cursor, $selectors) YIELD id, txId, seq, event "
        "RETURN id, txId, seq, event ORDER BY txId, seq",
        cursor=cursor, selectors=selectors,
        database_="neo4j"
    )
    events = [r.data() for r in records]
    # Advance cursor to last event id; keep current if no events
    next_cursor = events[-1]["id"] if events else cursor
    return events, next_cursor

# Bootstrap
with driver.session(database="neo4j") as s:
    cursor = s.run("CALL db.cdc.current() YIELD id RETURN id").single()["id"]

selectors = [{"select": "n", "labels": ["Person"]}]

import time
while True:
    events, cursor = poll_changes(cursor, selectors)
    for e in events:
        print(e["event"]["operation"], e["event"]["elementId"])
    time.sleep(1)

Confluent Cloud マネージドコネクター

Confluent Cloud は、Neo4j Sink コネクターをフルマネージドサービスとしてホストしています(JAR のアップロードは不要です)。

セルフマネージドとの設定の違い:

  • connector.class フィールドはありません — UI/API で選択します
  • 認証情報は Confluent Cloud シークレットマネージャーまたは直接 JSON で指定します
  • プライベートエンドポイントに対応しています(AWS PrivateLink、Azure Private Link、GCP PSC)
  • マネージドアップグレード — 必要に応じてコネクターのバージョンを明示的に固定します

Confluent Cloud で必須のフィールド:

{
  "kafka.auth.mode": "KAFKA_API_KEY",
  "kafka.api.key": "...",
  "kafka.api.secret": "...",
  "input.data.format": "JSON",
  "neo4j.uri": "neo4j+s://...",
  "neo4j.authentication.type": "BASIC",
  "neo4j.authentication.basic.username": "neo4j",
  "neo4j.authentication.basic.password": "..."
}

トピックごとに 1 つの戦略のみ使用できます。同じトピックで Cypher と Pattern を混在させることはできません。


Schema Registry(Avro / JSON Schema)

Source コネクターは常にスキーマ対応のメッセージを生成するため、コンバーターを設定する必要があります:

{
  "key.converter": "io.confluent.connect.avro.AvroConverter",
  "key.converter.schema.registry.url": "https://your-schema-registry",
  "value.converter": "io.confluent.connect.avro.AvroConverter",
  "value.converter.schema.registry.url": "https://your-schema-registry"
}

JSON Schema の場合:

{
  "value.converter": "io.confluent.connect.json.JsonSchemaConverter",
  "value.converter.schema.registry.url": "https://..."
}

Sink コンバーターは Source と一致させる必要があります。Avro Sink は JSON Schema の Source メッセージを消費できません。


よくあるエラー

エラー原因修正方法
CDC is not enableddb.cdc.enabled が設定されていない/誤ったティアneo4j.conf で有効にするか、EE/BC/VDC にアップグレードします
DB の復元後に発生する Invalid cursorバックアップによってカーソルが無効になりますneo4j.start-from を NOW または EARLIEST にリセットします
Cannot merge node using nullメッセージにキーのプロパティがありませんメッセージスキーマを検証し、Cypher に null チェックを追加します
再起動後にメッセージが再生されるEOS が設定されていませんneo4j.eos-offset-label と NODE KEY 制約を追加します
不正なメッセージでコネクターが停止するerrors.tolerance=none(デフォルト)errors.tolerance=all と DLQ トピックを設定します
Sink で SchemaException が発生するSource/Sink 間でコンバーターが一致していません両端でキー/値のコンバーターを一致させます
db.cdc.query から空のイベントが返されるカーソルが現在を指しています再生するには db.cdc.earliest() を使用します。新しいトランザクションが発生するまで待ちます

参考資料


チェックリスト

  • CDC を使用する Source または Sink の場合、CDC の利用可否を確認済み(Neo4j 5.13+ EE / Aura BC / VDC)
  • Sink のインポート前に一意性/NODE KEY 制約を作成済み(MERGE で使用)
  • neo4j.eos-offset-label を使用する場合、EOS 制約を作成済み
  • 認証情報はシークレットプロバイダー経由で指定 — 設定にハードコードしない
  • Cypher Sink クエリでは、冪等性のために CREATE ではなく MERGE を使用
  • 本番環境の Sink に errors.tolerance=all と DLQ を設定済み
  • Source:neo4j.query.streaming-property にインデックスを設定済み
  • Schema Registry コンバーターは Source と Sink の両側で一致
  • DB の復元後:CDC カーソルを再設定(neo4j.start-from)
  • CDC カーソルループ:処理が成功した後にのみカーソルを進める

コメント