windows環境におけるwikipediaのdump

# wikipediaをPCで使う

https://qiita.com/grachro/items/11e59d16a929d27e274e

こちらを参考に進めていただけたらよいのですが、windows環境ではmysqlとの兼ね合いで文字化けが起きたりしたので忘備録的に残しておきます
ページコンテンツの取り込みも成功したので、こちらに関してもメモ

# 環境
- windows 10
- MySQL 5.7
- Ubuntu 16.04

# mysqlのダウンロード

https://www.microsoft.com/ja-jp/download/details.aspx?id=40784
こちらを先にインストールしておきます

https://dev.mysql.com/downloads/windows/installer/5.7.html
mysql 5.7を使います
私は以下をダウンロードしました
mysql-installer-web-community-5.7.29.0.msi

- Choosing a Setup TypeにてServer onlyを選択
- High AvaiabilityにてStandalone MySQL Server/ Classic MySQL Replicationを選択
- Accounts and Rolesでは好きなパスワードを入力(ここではpasswordで統一します)
- 他はデフォルトで

環境変数に以下を追加

```
C:\Program Files\MySQL\MySQL Server 5.7\bin
```

コマンドプロンプトから

```
mysql -u root -p
Enter Password: password
```

と打って中に入れたらおっけー

## MySQLの設定
高速化のために以下のようにconfファイルを修正
http://shizm.hatenablog.com/entry/20101214/1292320319

C:/ProgramData/MySQL/MySQL Server 5.7/my.ini

```bash:my.ini
[client]
port=3306
+ default-character-set=utf8

[mysql]
no-beep
+ default-character-set=utf8

[mysqld]
port=3306
datadir=C:/ProgramData/MySQL/MySQL Server 5.7/Data
default-storage-engine=INNODB
- sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
+ sql-mode=""
log-output=FILE
general-log=0
general_log_file="DESKTOP-8A2LKVH.log"
slow-query-log=1
slow_query_log_file="DESKTOP-8A2LKVH-slow.log"
long_query_time=10
log-error="DESKTOP-8A2LKVH.err"
relay_log="DESKTOP-8A2LKVH-relay"
server-id=1
report_port=3306
lower_case_table_names=1
- secure-file-priv="C:/ProgramData/MySQL/MySQL Server 5.7/Uploads"
+ secure-file-priv=""
max_connections=151
table_open_cache=2000
tmp_table_size=95M
thread_cache_size=10
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=181M
key_buffer_size=8M
read_buffer_size=64K
read_rnd_buffer_size=256K
- innodb_flush_log_at_trx_commit=1
+ innodb_flush_log_at_trx_commit=0
innodb_log_buffer_size=1M
innodb_buffer_pool_size=8M
innodb_log_file_size=48M
innodb_thread_concurrency=17
innodb_autoextend_increment=64
innodb_buffer_pool_instances=8
innodb_concurrency_tickets=5000
innodb_old_blocks_time=1000
innodb_open_files=300
innodb_stats_on_metadata=0
innodb_file_per_table=1
innodb_checksum_algorithm=0
back_log=80
flush_time=0
join_buffer_size=256K
max_allowed_packet=4M
max_connect_errors=100
open_files_limit=4161
sort_buffer_size=256K
table_definition_cache=1400
binlog_row_event_max_size=8K
sync_master_info=10000
sync_relay_log=10000
sync_relay_log_info=10000
+ skip_innodb_doublewrite
+ character-set-server=utf8
+ expire_logs_days=1

+ [mysqldump]
+ default-character-set=utf8
```

最後にコマンドをいくつか追加したので、再起動します
windowsキーを押した後に、サービス　と検索
MySQL5.7を選択して再起動でおｋ
文字コードはすべてutf-8で統一します

# category
単語から、そのカテゴリーを検索します
さらに上位カテゴリをたどって、特定のカテゴリの下位カテゴリに属するかなどもできそうです

## download

https://dumps.wikimedia.org/jawiki/latest/
から

- jawiki-latest-category.sql.gz
- jawiki-latest-categorylinks.sql.gz
- jawiki-latest-page.sql.gz

をダウンロードして解凍


## Wikipedia categoryのインポート

-vをつけると、途中でrestoreが終了することがあります

```
$ mysql -u root -p
mysql> create database wikipedia;
mysql> exit;
$ mysql -u root -p --default-character-set=utf8 wikipedia < jawiki-latest-categorylinks.sql
$ mysql -u root -p --default-character-set=utf8 wikipedia < jawiki-latest-category.sql
$ mysql -u root -p --default-character-set=utf8 wikipedia < jawiki-latest-page.sql
```

restoreには結構時間がかかります(categoryで12sec, categorylinksは具体的な時間は覚えていませんが一晩放置したら終わりました, pageは18分程度)
進捗は

```
$ mysql -u root -p
mysql> use wikipedia;
mysql> show tables;
mysql> select count(*) from <table名>;
```

とすることで途中経過を確認できます
それぞれ

```

mysql> select count(*) from category;
+----------+
| count(*) |
+----------+
|   263753 |
+----------+

mysql> select count(*) from categorylinks;
+----------+
| count(*) |
+----------+
|  9320350 |
+----------+

mysql> select count(*) from page;
+----------+
| count(*) |
+----------+
|  3552887 |
+----------+
```

となればおｋです
(この辺の数字はバージョンによってかなり変動あるかと思います。2019年にしたときはcategolylinksは800万くらいだった気がします。参考程度に)

# wikipedia categoryの検索
まずはsqlを発行してみます。
ページタイトルからカテゴリを抽出

```
# windowsのコマンドプロンプトから操作する場合、かならずこれを打つこと
$ chcp 65001
$ mysql -u root -p
mysql> select cl_to from categorylinks inner join page on page.page_id = categorylinks.cl_from where page.page_title = '幕張メッセ';

| 1986年設立の企業
| 1989年竣工の建築物
| 1989年開業の施設
| 1997年竣工の建築物
| 2020年東京オリンピックの競技会場
| ウィキデータにある座標
| 公共建築賞
| 内容の精度・確度に欠けている可能性のある記事
| 出典のページ番号が要望されている記事
| 出典を必要とする記述のある記事/2016年8月
| 千葉市のスポーツ施設
| 千葉県のコンサート会場
| 幕張新都心
| 日本のコンベンションセンター
| 日本のバスケットボール競技施設
| 日本のバレーボール競技施設
| 日本のボクシング会場
| 日本の屋内競技施設
| 槇文彦
| 第32回BCS賞
| 美浜区の企業
| 美浜区の建築物

```
幕張メッセがどんな感じの概念なのか理解できそうです

# 本文記事(Article)

Articleなどの本文情報はなぜかxmlにて公開されており、そのまま読み込んで使おうとするとものすごいメモリと検索時間を使います。MySQLへの変換に取り組みました

ググってみるとarticleをSQLiteにしてくれている人がいました
http://koiroha.blogspot.com/2017/04/how-to-get-wikipedia-dump-as-plaintext.html
https://drive.google.com/file/d/0Bw3bmWvXtpUYR2ZKQWplVzVrUW8/view

ただ今回どうせならMySQLがほしいので別の方法を探します
xml2sqlというツールを使うのがよさそう
http://qwik.jp/senna/wikipedia_ja_test.html

本文記事の検索だけ必要な場合は、上記の[category]の項目はすべて飛ばしてもらって大丈夫です

## 本文記事の入手

https://dumps.wikimedia.org/jawiki/latest/
から
jawiki-latest-pages-articles.xml.bz2

を入手

Ubuntuでないと面倒なので、windowsユーザーはwindows subscription linuxなどを使ってください

```bash
$ git clone https://github.com/Tietew/mediawiki-xml2sql.git
$ cd mediawiki-xml2sql
$ ./configure
$ make
$ sudo make install
```

解凍します

```bash
$ bzip2 -d jawiki-latest-pages-articles.xml.bz2
```

ファイルを作成

```bash
$ cat jawiki-latest-pages-articles.xml | sed -e 's/<dbname>.*<\/dbname>//' -e 's/<ns>.*<\/ns>//' -e 's/<parentid>.*<\/parentid>//' -e 's/<sha1>.*<\/sha1>//' -e 's/<model>.*<\/model>//' -e 's/<format>.*<\/format>//' -e 's/<redirect>.*<\/redirect>//' -e 's/<redirect.*\/>//' | xml2sql
```

- text.txt(11.3GBくらい)
- revision.txt(0.28GBくらい)
- page.txt(0.22GBくらい)

のファイルを作成します（corei7+SSH+メモリ32G+デスクトップ環境で5分30秒ほどかかりました）
これが入手出来たらUbuntuでの作業は終了です
WSLを使っている人は問題ないですが、Linuxからwindowsへのコピーのためexfat形式にフォーマットさせた32GBくらいのUSBを用意しておくことをお勧めします。ネットワーク経由だと容量とか通信制限とか時間とか、いろいろ面倒です

## インストール

テーブルを作成します
https://phabricator.wikimedia.org/source/mediawiki/browse/master/maintenance/tables.sql
こちらからsqlファイルをダウンロードしてください
そうして、「page」「category」「categorylinks」の部分のcreate table とindexをコメントアウトしましょう
しなかったら「exsist table XX」みたいなエラーが出て、drop talbeで一つ一つ空のテーブルを消す羽目になります(categoryの項目を飛ばしている人はコメントアウト必要ありません)

```bash
CREATE TABLE /*_*/page (
↓
-- CREATE TABLE /*_*/page (
# 「--」で一行コメントアウトになります
# この感じでcreate tableとその中身、create index系をコメントアウトしていく
```

コメントアウトが終わったら

```
$ mysql -u root -p wikipedia < tables.sql
```

これで空のテーブルを作成できます
その後

- text.txt
- revision.txt
- page.txt

これを

```
C:\ProgramData\MySQL\MySQL Server 5.7\Data\tmp
```

にコピーしておきます
page.txtはcategoryの項目ですでにデータが格納されていますが、本文検索を優先させるためにこちらで上書きします
そしてインポートのコマンドをコマンドプロンプトから打ちます

```
$ mysqlimport -u root wikipedia -p tmp\page.txt
# 14分ほどかかった
# Records: 2482846  Deleted: 0  Skipped: 0  Warnings: 7448519

$ mysqlimport -u root wikipedia -p tmp\revision.txt
# こちらも14分ほど

$ mysqlimport -u root wikipedia -p tmp\text.txt
# こちらは18分ほど
```

インポート出来たことを確認

```
mysql > select count(*) from page;
+----------+
| count(*) |
+----------+
|  2482846 |
+----------+
1 row in set (0.93 sec)

mysql> select count(*) from revision;
+----------+
| count(*) |
+----------+
|  2482846 |
+----------+
1 row in set (0.93 sec)

mysql> select count(*) from text;
+----------+
| count(*) |
+----------+
|  2482846 |
+----------+
1 row in set (1 min 33.06 sec)

```

中身も確認してみる

```
# windowsのコマンドプロンプトから操作する場合、かならずこれを打つこと
chcp 65001

mysql -u root -p
mysql> select page_title from page order by rand() limit 10;

+---------------------------------------------+
| page_title                                  |
+---------------------------------------------+
| 山田恵庸                                    |
| ブレーズド回折格子                          |
| 丹下左膳_(1967年のテレビドラマ)             |
| クリストファー・イシャーウッド              |
| 熱血!テレビ番長                             |
| かぐや姫_竹御殿                             |
| キューバを舞台とした映画作品                |
| 半沢孝麿                                    |
| 流田Project_VSスーパー戦隊+宇宙刑事ギャバン |
| 気がつけばあなた                            |
+---------------------------------------------+
10 rows in set (4.42 sec)
```

```

mysql> select text.old_text from revision inner join page on revision.rev_id=page.page_latest inner join text on revision.rev_text_id=text.old_id  where page.page_title="サクラ";

<前略>

| {{Redirect5|||さくら|桜}}
{{生物分類表
|色 = lightgreen
|名称 = サクラ
|画像 = [[File:Sakura153.jpg|thumb|桜 札幌円山公園]]<!-- 日本のサクラに限る必要は全くないが、海外産では種/品種がある程度確かなものが望ましい。[[File:Cherry 

<中略>

'''サクラ'''（'''桜'''）は、[[バラ科]][[モモ亜科]][[スモモ属]]（サクラ属）<ref>[http://kotobank.jp/word/%E6%A1%9C コトバンク‐桜]小学館の『[[大辞泉]]』の解説に「バラ科サクラ属の落葉高木の総称」と記され、また、三省堂の『[[大辞林]]』第三版の解説に「バラ科サクラ属の落葉高木または低木」と記されている。</ref>(Prunus, Cerasus, Japanese cherry, Sakura) の[[落葉性|落葉樹]]の総称。

サクラは[[春]]に咲かさせる[[花]]により、日本文化に馴染みの深い植物である（[[#日本人とサクラ]]）。また、日本において観賞用として植えられているサクラの多くは[[ソメイヨシノ]]という[[品種]]である。英語では桜の花のことを[[w:Cherry blossom|Cherry blossom]]と呼ぶのが一般的であるが、日本文化の影響から、sakuraと呼ばれることも多くなってきている。

<後略>

1 row in set (1.04 sec)

```

これで各種言語からwikipediaの記事にアクセスできそうです
wikipediaは様々な観点から解説されているので、応用例がいろいろ考えられそうですね