dak ブログ

python、rubyなどのプログラミング、MySQL、サーバーの設定などの備忘録。レゴの写真も。

jsonl のデータをオブジェクトとして MySQL に格納

2022-08-20 18:07:52 | mysql
jsonl 形式のデータをオブジェクトとして mysql に格納する方法のメモ。
以下の jsonl のデータを MySQL に格納します。
■登録データ
{"id": "01", "x": 30, "y": 170}
{"id": "02", "x": 20, "y": 180}
{"id": "03", "x": 25, "y": 160}
{"id": "04", "x": 40, "y": 175}
{"id": "05", "x": 45, "y": 180}

■MySQL のテーブル定義
create table test1 (
  obj  json,
  id   varchar(16) generated always as (json_unquote(obj->"$.id")) stored,
  x    integer generated always as (json_unquote(obj->"$.x")) stored,
  y    integer generated always as (json_unquote(obj->"$.y")) stored,

  primary key (id),
  index (x, y),
  index (y, x)
);

MySQL に登録する際に id を primary key とし、x、y にはインデックスを張ります。

■MySQL へのデータ登録
上記の jsonl 形式のデータを /var/lib/mysql-files/test1.jsonl に保存し、MySQL に load します。
このとき、fields terminated by '\t' を指定することで jsonl のデータが分割されないようにします。
load data infile '/var/lib/mysql-files/test1.jsonl' ignore into table test1 fields terminated by '\t' (obj);

■登録内容の確認
select * from test1;

obj     id      x       y
{"x": 30, "y": 170, "id": "01"} 01      30      170
{"x": 20, "y": 180, "id": "02"} 02      20      180
{"x": 25, "y": 160, "id": "03"} 03      25      160
{"x": 40, "y": 175, "id": "04"} 04      40      175
{"x": 45, "y": 180, "id": "05"} 05      45      180

■primary key の確認
以下の通り、id を指定した検索では PRIMARY KEY が利用されていることがわかります。
explain select id, x, y from test1 where id = '03'\G;

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
   partitions: NULL
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 66
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL


MySQL での json 型のデータへのインデックス

2022-08-20 17:32:12 | mysql
MySQL で json 型のデータにインデックスを張る方法のメモ。
テーブル定義でインデックスを張りたいデータ項目(x) に "generated always as (json_unquote(obj->"$.x")) stored" を指定します。
■テーブル定義
create table test1 (
  id   varchar(16) not null,
  obj  json,
  x    integer generated always as (json_unquote(obj->"$.x")) stored,
  y    integer generated always as (json_unquote(obj->"$.y")) stored,

  primary key (id),
  index (x, y),
  index (y, x)
);

■データ登録
insert into test1 set id = '01', obj = '{"id": "01", "x": 30, "y": 170}';
insert into test1 set id = '02', obj = '{"id": "02", "x": 20, "y": 180}';
insert into test1 set id = '03', obj = '{"id": "03", "x": 25, "y": 160}';
insert into test1 set id = '04', obj = '{"id": "04", "x": 40, "y": 175}';
insert into test1 set id = '05', obj = '{"id": "05", "x": 45, "y": 180}';

■検索
select id, x from test1 where x >= 30\G;

*************************** 1. row ***************************
id: 01
 x: 30
*************************** 2. row ***************************
id: 04
 x: 40
*************************** 3. row ***************************
id: 05
 x: 45

■実行計画
上記のクエリでは key に x が使われていることがわかります。
explain select id, x from test1 where x >= 30\G;

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
   partitions: NULL
         type: range
possible_keys: x,y
          key: x
      key_len: 5
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using where; Using index


Node.js での jsdom を利用した HTML からのテキスト抽出

2022-08-20 16:16:19 | Node.js
Node.js で jsdom を利用して HTML からテキストを抽出する方法のメモ。
dom = new JSDOM(...) で DOM を生成すると、dom.window.document で HTML の DOM ツリーを参照できます。
nodeType が TEXT_NODE の場合に、nodeValue に格納されているテキストを抽出します。

■プログラム
const jsdom = require('jsdom');

// 以下が対象の HTML
const html = `
<html>
<head>
<title>test</title>
<meta keyword="kw1, kw2, kw3">
</head>
<body>
abc
<div>div1-1</div>
<div>div2-1<div>div2_2-1</div>div2-2</div>
<div>div3-1</div>
xyz
</body>
</html>
`;

// DOM 生成
const dom = new jsdom.JSDOM(html);

// 再帰的に DOM ツリーをたどってテキストを抽出
function get_texts(node, texts=[]) {
  if (node.nodeType === node.TEXT_NODE) {
    texts.push(node.nodeValue);
  }
  else if (node.nodeType === node.ELEMENT_NODE) {
    for (const child of node.childNodes) {
      get_texts(child, texts);
    }
  }

  return texts;
}

const doc = dom.window.document;
const texts = get_texts(doc.body);
console.log(texts);

■実行結果
[
  '\nabc\n',
  'div1-1',
  '\n',
  'div2-1',
  'div2_2-1',
  'div2-2',
  '\n',
  'div3-1',
  '\nxyz\n\n\n'
]