0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Draft.jsのJsonデータからテキスト部分のあいまい検索をする

Posted at

Draft.jsとは、Facebook(現在Meta社)が開発しているReactにリッチエディタを簡単に導入できるライブラリです。

Draft.jsはエディタに入力された文字のスタイル(太字など)も管理するため、テキストを入力するとDraft.jsではスタイルを含んだJsonを返します。

例えば、単に テスト投稿ですとエディタに入力すると以下のようなJsonが生成されます。

{
  "blocks": [
    {
      "key": "4s107",
      "data": {
      },
      "text": "テスト投稿です",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    }
  ],
  "entity_map": {
  }
}

この記事では、上記のようなJsonデータからテキスト部分に対して、あいまい検索するためのクエリが、普段Jsonをそれほど使わない私には、難しく、記事もなかなかで出てこなかったので、今回記事にしました。

なお、今回はJson型ではなく、JSONB型を扱っています。DBはPostgreSQLを利用しています。

あいまい検索するSQL

今回、contentというカラムがjsonb型になっており、そのカラムに以下のデータが入っています。

{
  "blocks": [
    {
      "key": "4s107",
      "data": {
      },
      "text": "テスト投稿です",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    }
  ],
  "entity_map": {
  }
}

SQLはこちらです。

SELECT id, content
FROM posts, JSONB_ARRAY_ELEMENTS(content->'blocks') AS block
WHERE block ->> 'text' LIKE '%投稿%'

以下補足

JSONB_ARRAY_ELEMENTSとは何かというと、、、

JSONB_ARRAY_ELEMENTSの参考:https://www.postgresql.jp/document/13/html/functions-json.html

たとえば、こんなJSONがあり、このblocksの配列を返したいときに

JSONの例
{
  "blocks": [
    {
      "key": "bk52m",
      "data": {
      },
      "text": "yahoo",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    },
    {
      "key": "514td",
      "data": {
      },
      "text": "google",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    },
    {
      "key": "7kqtk",
      "data": {
      },
      "text": "edge",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    },
    {
      "key": "a1hj2",
      "data": {
      },
      "text": "safari",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    },
    {
      "key": "ehcpf",
      "data": {
      },
      "text": "https://example.com",
      "type": "unstyled",
      "depth": 0,
      "entity_ranges": [
      ],
      "inline_style_ranges": [
      ]
    }
  ],
  "entity_map": {
  }
}
SELECT id, JSONB_ARRAY_ELEMENTS(content->'blocks') as blocks
FROM posts;

上記のSQLでblocksの配列が返ってきます

# SELECT id, JSONB_ARRAY_ELEMENTS(content->'blocks') as blocks
FROM posts;
                  id                  |                                                                    blocks
--------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------
 beda9f03-3131-4845-b43a-a422ce82a59d | {"key": "4s107", "data": {}, "text": "テスト投稿です", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
 42733b11-b091-4d05-886a-af9fb942eb5b | {"key": "bk52m", "data": {}, "text": "yahoo", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
 42733b11-b091-4d05-886a-af9fb942eb5b | {"key": "514td", "data": {}, "text": "google", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
 42733b11-b091-4d05-886a-af9fb942eb5b | {"key": "7kqtk", "data": {}, "text": "edge", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
 42733b11-b091-4d05-886a-af9fb942eb5b | {"key": "a1hj2", "data": {}, "text": "safari", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
 42733b11-b091-4d05-886a-af9fb942eb5b | {"key": "ehcpf", "data": {}, "text": "https://example.com", "type": "unstyled", "depth": 0, "entity_ranges": [], "inline_style_ranges": []}
(6 rows)

なので、上記のblocksのうち、さらにtext部分を抽出するには、、、

=# SELECT id, JSONB_ARRAY_ELEMENTS(content->'blocks') ->> 'text' as text
FROM posts;
                  id                  |        text
--------------------------------------+---------------------
 beda9f03-3131-4845-b43a-a422ce82a59d | テスト投稿です
 42733b11-b091-4d05-886a-af9fb942eb5b | yahoo
 42733b11-b091-4d05-886a-af9fb942eb5b | google
 42733b11-b091-4d05-886a-af9fb942eb5b | edge
 42733b11-b091-4d05-886a-af9fb942eb5b | safari
 42733b11-b091-4d05-886a-af9fb942eb5b | https://example.com
(6 rows)

上記のようなSQLでtext部分の抽出ができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?