Skip to content

Adapt for json - #18

Closed
w256 wants to merge 2 commits into
y-ken:masterfrom
w256:adapt_for_json
Closed

Adapt for json#18
w256 wants to merge 2 commits into
y-ken:masterfrom
w256:adapt_for_json

Conversation

@w256

@w256 w256 commented Feb 20, 2016

Copy link
Copy Markdown

大変便利にありがたく使わせていただいております。
mysqlのフィールドにjsonを使っている場合でも、esに登録できるように改変しました。

以下は改変作業の具体的な内容となります。


mysqlのgeometoryフィールドに以下のようなjsonが入っており、それをesにロードしたい場合、うまくいかない事象がありました。

  • {"type": "Polygon", "coordinates": [[[136.8, 35.1], [136.8001, 35.1], [136.8001, 35.10001], [136.8, 35.100012], [136.8, 35.1]]]}

そこで、esに送信しているデータを確認しましたところ、本対応前は以下のようになっていました。

  • "geometry":"{"type": "Polygon", "coordinates": [[[136.8, 35.1], [136.8001, 35.1], [136.8001, 35.10001], [136.8, 35.100012], [136.8, 35.1]]]}"}

以下のように登録前に置換を行うように変更したところロードが成功するようになりました。

  1. 「\"」を 「"」に置換
  2. 「"{」を 「{」に置換
  3. 「"}」を 「}」に置換

@y-ken

y-ken commented Sep 16, 2017

Copy link
Copy Markdown
Owner

すみません、こちらは副作用が想定できるため対応が検討中のままでした。
JSON型と判定できる中身の場合に、エスケープしない処理をする手法が良さそうです。

y-ken added a commit that referenced this pull request Jun 16, 2026
MySQL JSON columns are returned by the driver as plain strings, so they
reached Elasticsearch as escaped strings instead of nested objects. Add a
`json_columns` option that lists the columns whose values should be parsed
into nested objects before they are emitted.

- in_mysql_replicator: new `json_columns` config_param
- in_mysql_replicator_multi: new `json_columns` settings column (varchar)
- Malformed JSON, non-string and unlisted columns are left untouched, so
  the default behavior is unchanged (opt-in, no side effects)
- Document that this targets Elasticsearch; leave it empty for Solr or
  destinations that cannot store JSON objects
- Unit tests for parsing/config and single & multi E2E that assert the
  column is indexed as a nested object

Refs #18

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@y-ken y-ken mentioned this pull request Jun 16, 2026
@y-ken

y-ken commented Jun 16, 2026

Copy link
Copy Markdown
Owner

ご報告と PR、ありがとうございます。ここで挙げていただいた問題は #48(マージ済み・v1.2.0 で同梱)で別アプローチにより解決しましたので、その内容を共有したうえでクローズさせてください。

同じ問題が解決します

ご提示の geometry 列({"type": "Polygon", "coordinates": [[[136.8, 35.1], ...]]})は、対応前は Elasticsearch にエスケープされた文字列として届いていました:

"geometry":"{\"type\": \"Polygon\", \"coordinates\": [[[136.8, 35.1], ...]]}"

#48 で追加した json_columns を使い、対象列を指定すると:

# mysql_replicator の場合
json_columns geometry

その列だけを JSON.parse してから送信するため、ネストされたオブジェクトとして正しくインデックスされます:

"geometry":{"type":"Polygon","coordinates":[[[136.8,35.1], ...]]}

mysql_replicator_multi でも、settings テーブルの json_columns 列に同様に指定できます。

なぜ置換ではなくこの方式にしたか

いただいた \"" / "{{ / "}} の置換案は、出力前のすべての列・すべての値に無条件で適用されるため、JSON ではない通常のテキスト列にたまたま "{\" が含まれていると壊れてしまう懸念がありました。

json_columns 方式は:

  • 指定した列だけを対象にし、他の列には一切触れません。
  • 文字列の機械的な置換ではなく JSON.parse で厳密にパースします。
  • 不正な JSON / 文字列以外の値はそのまま残すので、非 JSON データを壊しません。

という点で、同じ目的をより安全に達成できます。

この機能はまさにこの Issue の要望から生まれたものです。ありがとうございました 🙏 v1.2.0 で利用可能になります。

@y-ken y-ken closed this Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants