0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Notionの研究業績DBからresearchmap V2 CSVを生成・更新する

0
Last updated at Posted at 2026-06-08

はじめに

前回の記事では、Notionの Publications データベースを研究業績の正本として管理し、MarkdownやHTMLに出力する運用を紹介しました。

前回記事

関連GitHubリポジトリ

この記事では、その続きとして、同じNotion DBからresearchmap V2 CSVを生成し、researchmap上の既存業績を更新する運用を紹介します。

前回の基本方針は次の通りです。

Notion Publications DB
  ↓
fetch
  ↓
cache/publications.json
  ↓
Markdown / HTML / TXT

今回はここに、researchmap CSV出力を追加します。

Notion Publications DB
  ↓
fetch
  ↓
cache/publications.json
  ↓
researchmap V2 CSV
  ↓
researchmapへアップロード

さらに、researchmapからエクスポートしたCSVを使って、researchmap上の業績IDをNotionへ書き戻すことで、次回以降は既存業績を安全に更新できるようにします。

この記事で扱うこと

この記事で扱うのは、researchmap APIではなく、researchmapのCSVインポート・エクスポートを使う運用です。

扱うこと:

  • Notion DBからresearchmap V2 CSVを生成する
  • researchmapへCSVをアップロードする
  • researchmapからCSVをエクスポートする
  • エクスポートCSVとNotionデータを照合する
  • Researchmap ID をNotionへ書き戻す
  • 次回以降は update / doc / ID指定 でCSVを生成する

扱わないこと:

  • researchmap APIで直接更新する
  • researchmap側の編集内容をNotionへ自動で取り込む
  • 完全な双方向同期を作る
  • すべてのresearchmap業績種別に完全対応する

この運用では、あくまで Notion DBを正本 とします。researchmapからエクスポートしたCSVは、既存業績IDを確認するための参照データとして使います。

ResearchmapのCSV仕様については、こちらの情報を参照しています。

全体像

初回は、Notion側にresearchmapの業績IDがありません。そのため、まずは insert / merge としてCSVを生成します。

初回:

Notion
  ↓
researchmap CSV
  ↓
researchmapにアップロード
  ↓
researchmapからCSVをエクスポート
  ↓
Notion項目と照合
  ↓
Researchmap IDをNotionへ書き戻す

一度 Researchmap ID がNotionに入れば、次回以降は既存業績IDを指定して更新できます。

次回以降:

Notion with Researchmap ID
  ↓
researchmap CSV
  ↓
update / doc / ID指定
  ↓
researchmap上の既存業績を更新

この切り替えが重要です。

Researchmap ID なし
  → insert / merge / IDなし

Researchmap ID あり
  → update / doc / ID指定

IDなしで毎回 insert すると、重複登録や類似判定エラーの原因になります。継続運用では、researchmap側の業績IDをNotionに保持し、それを使って更新する方が安全です。

前提

前回の記事で、以下ができている前提です。

  • Notionに Publications DBがある
  • Notionに Authors DBがある
  • Publications DBから Authors DBへrelationしている
  • Notion integrationを作成済み
  • NOTION_KEY, database_id, authors_db_id が環境変数に入っている
  • uv run notion-export fetch でNotion DBを取得できる

また、この記事ではPython環境管理に uv を使います。

researchmap CSVの基本

researchmap V2 CSVには、通常のCSVとは少し違う約束があります。

代表的には次のような点です。

  • 1行目に業績種別を書く
  • 2行目にヘッダを書く
  • 3行目以降にデータを書く
  • 未設定項目は空欄ではなく null と書く
  • アクション名アクションタイプ が重要
  • 既存業績を更新する場合は ID を指定する

例えば、講演・口頭発表等の場合、1行目は次のようになります。

presentations

2行目にヘッダが入り、3行目以降にデータが入ります。

presentations
アクション名,アクションタイプ,類似業績マージ優先度,ID,タイトル(日本語),タイトル(英語),...
insert,merge,null,null,...,...

この記事では、主に presentations、つまり講演・口頭発表等のCSVを例に説明します。

Notion側に追加するプロパティ

前回のNotion DBに、researchmap連携用のプロパティを追加します。

最低限追加したいものは次の通りです。

プロパティ 用途
Researchmap ID rich text researchmap側の業績ID
Sync to Researchmap checkbox researchmapへ出力するか
Researchmap Type select researchmap上の種別を上書きしたい場合
Language Code select jpn / eng
Country Code select / rich text JPN, USA, CAN など
Invited checkbox 招待講演か
Visibility select disclosed, researchers_only, closed
Major checkbox 主要業績か
Researchmap Sync Status select 照合状態の管理用

実際には、すべてを毎回手入力する必要はありません。

空欄でもよいもの

以下は、空欄ならスクリプト側で推定・補完する運用にできます。

プロパティ 補完方針
Researchmap Type Type から推定
Language Code Type から推定
Visibility disclosed
Major FALSE
Researchmap Sync Status 任意の管理用ステータス

例えば、Researchmap Type は次のように推定できます。

Original Paper           -> published_papers
Review paper             -> published_papers
International conference -> presentations
国内学会                  -> presentations
Preprint                 -> misc

Language Code も、おおむね次のように推定できます。

国内学会                  -> jpn
International conference -> eng
Original Paper           -> eng
Review paper             -> eng
Preprint                 -> eng

手入力した方がよいもの

一方で、次のものは手入力した方が安全です。

プロパティ 理由
Sync to Researchmap researchmapに出すかどうかは人間判断
Country Code 国際会議の会場国は自動推定しにくい
Invited 招待講演かどうかは自動では分からない

国内学会であれば Country Code = JPN と自動補完できますが、国際会議は USA, CAN, SGP などを明示的に入れておく方が安全です。

国コードの例

researchmapの 国・地域 には、3文字の国コードを入れます。

よく使いそうな例です。

Country Code
日本 JPN
アメリカ USA
カナダ CAN
シンガポール SGP
オーストラリア AUS
ドイツ DEU
アイルランド IRL
イタリア ITA

Notionの Country Code には、この3文字コードを入れておきます。

config.yamlの設定

Notion側のプロパティ名と、スクリプト内部で使う名前を config.yaml で対応づけます。

例です。

properties:
  name: Name
  title: Name
  authors_relation: Authors list
  type: Type
  journal: Journal
  venue: Journal
  volume: Volume
  issue: Issues
  publication_date: Publication date
  pages: Page
  doi: DOI
  place: Place
  duration: Duration
  presentation: Presentation
  tags: Tags

  researchmap_id: Researchmap ID
  researchmap_type: Researchmap Type
  sync_to_researchmap: Sync to Researchmap
  researchmap_sync_status: Researchmap Sync Status

  language_code: Language Code
  country_code: Country Code
  invited: Invited
  visibility: Visibility
  major: Major

  arxiv_id: arXiv ID
  arxiv_url: arXiv URL
  journal_status: Journal Status
  related_journal_paper: Related Journal Paper

補完ルールも設定しておくと便利です。

researchmap:
  default_visibility: disclosed
  default_major: false
  default_language_code:
    国内学会: jpn
    International conference: eng
    Original Paper: eng
    Review paper: eng
    Preprint: eng
  default_country_code:
    国内学会: JPN
  type_mapping:
    Original Paper: published_papers
    Review paper: published_papers
    International conference: presentations
    国内学会: presentations
    Preprint: misc
  presentation_type_mapping:
    Oral: oral_presentation
    Poster: poster_presentation
  preprint_misc_type: technical_report

Notionから最新データを取得する

Notionを更新したら、まずキャッシュを更新します。

uv run notion-export fetch \
  --config config.yaml \
  --cache cache/publications.json

通常運用では、cache/publications.json を毎回上書きして構いません。別名保存は、デバッグや比較をしたいときだけで十分です。

researchmap用CSVを生成する

講演・口頭発表等、つまり presentations 用のCSVを生成します。

uv run notion-export researchmap export-csv \
  --config config.yaml \
  --cache cache/publications.json \
  --target presentations \
  --output outputs/researchmap_presentations.csv

先頭を確認します。

sed -n '1,10p' outputs/researchmap_presentations.csv

1行目が presentations、2行目がヘッダ、3行目以降がデータになっていればOKです。

CSVの中身を確認する

researchmapへアップロードする前に、actionやIDの状態を確認します。

uv run python - <<'PY'
import csv
from pathlib import Path
from collections import Counter

path = Path("outputs/researchmap_presentations.csv")

with path.open(encoding="utf-8-sig", newline="") as f:
    rows = list(csv.reader(f))

header = rows[1]
records = rows[2:]
idx = {h: i for i, h in enumerate(header)}

print("records:", len(records))
print("actions:", Counter(r[idx["アクション名"]] for r in records))
print("action types:", Counter(r[idx["アクションタイプ"]] for r in records))
print("ids set:", sum(1 for r in records if r[idx["ID"]] not in {"", "null"}))
print("ids null:", sum(1 for r in records if r[idx["ID"]] in {"", "null"}))
print("countries:", Counter(r[idx["国・地域"]] for r in records))
PY

初回で Researchmap ID がまだない場合は、次のようになります。

actions: Counter({'insert': 58})
action types: Counter({'merge': 58})
ids null: 58

Researchmap ID が書き戻された後は、次のようになります。

actions: Counter({'update': 58})
action types: Counter({'doc': 58})
ids set: 58

この状態なら、既存のresearchmap業績をID指定で更新できます。

初回登録

初回は、Notion側に Researchmap ID がありません。そのため、CSVは基本的に次のようになります。

insert,merge,null,null,...

このCSVをresearchmapにアップロードします。

アップロード後、researchmap側で業績IDが付与されます。このIDをNotionに書き戻すことで、次回以降は既存業績を更新できるようになります。

researchmapからCSVをエクスポートする

researchmapへのアップロード後、researchmapから対象業績のCSVをエクスポートします。

この記事では、例として presentations のエクスポートCSVを使います。

ファイル名は例えば次のようにします。

rm_presentations.csv

このCSVには、researchmap側の ID が含まれています。これをNotion側の業績と照合して、Researchmap ID として書き戻します。

researchmapエクスポートCSVを確認する

まず、researchmapからエクスポートしたCSVの概要を確認します。

uv run notion-export researchmap inspect-csv \
  --csv rm_presentations.csv

出力例です。

kind: presentations
record count: 58
with ID: 58
without ID: 0
action names: insert=58
action types: merge=58
duplicate title candidates: 0

researchmapからのエクスポートCSVでは、アクション名insert になっていることがあります。ただし、重要なのは ID が入っていることです。

Notionとresearchmap CSVを照合する

次に、Notionの業績とresearchmap CSVの業績を照合します。

現状の match-csv は presentations の照合を対象にしています。

uv run notion-export researchmap match-csv \
  --config config.yaml \
  --cache cache/publications.json \
  --csv rm_presentations.csv \
  --output outputs/researchmap_match_report.csv

照合レポートを確認します。

sed -n '1,40p' outputs/researchmap_match_report.csv

件数を集計するには、次のようにします。

uv run python - <<'PY'
import csv
from pathlib import Path
from collections import Counter

path = Path("outputs/researchmap_match_report.csv")

with path.open(encoding="utf-8-sig", newline="") as f:
    rows = list(csv.DictReader(f))

print("rows:", len(rows))
print(Counter(r.get("status") for r in rows))

for r in rows[:20]:
    print(r.get("status"), r.get("notion_title"), "=>", r.get("researchmap_id"), r.get("reason"))
PY

すべて対応できていれば、例えば次のようになります。

Counter({'matched': 58})

ambiguousnot_found がある場合は、手動確認します。

Researchmap IDをNotionへ書き戻す

現状の match-csv / sync-ids は presentations の照合を対象にしています。

まずはdry-runで確認します。

uv run notion-export researchmap sync-ids \
  --config config.yaml \
  --cache cache/publications.json \
  --csv rm_presentations.csv \
  --dry-run

この段階ではNotionには書き込みません。

出力例です。

Write candidates: 58
Skipped: 0

問題なければ、--apply を付けて実際に書き戻します。

uv run notion-export researchmap sync-ids \
  --config config.yaml \
  --cache cache/publications.json \
  --csv rm_presentations.csv \
  --apply

成功すると、Notion側の Researchmap ID にIDが入ります。

その後、再fetchして確認します。

uv run notion-export fetch \
  --config config.yaml \
  --cache cache/publications.json
uv run python - <<'PY'
import json
from pathlib import Path

data = json.loads(Path("cache/publications.json").read_text(encoding="utf-8"))

with_id = [x for x in data if x.get("researchmap_id")]
print("items with Researchmap ID:", len(with_id))

for item in with_id[:10]:
    print(item.get("title"), "=>", item.get("researchmap_id"))
PY

次回以降の更新

Researchmap ID がNotionに入った後にCSVを生成すると、該当行は update / doc / ID指定 になります。

uv run notion-export researchmap export-csv \
  --config config.yaml \
  --cache cache/publications.json \
  --target presentations \
  --output outputs/researchmap_presentations.csv

確認します。

uv run python - <<'PY'
import csv
from pathlib import Path
from collections import Counter

path = Path("outputs/researchmap_presentations.csv")

with path.open(encoding="utf-8-sig", newline="") as f:
    rows = list(csv.reader(f))

header = rows[1]
records = rows[2:]
idx = {h: i for i, h in enumerate(header)}

print("records:", len(records))
print("actions:", Counter(r[idx["アクション名"]] for r in records))
print("action types:", Counter(r[idx["アクションタイプ"]] for r in records))
print("ids set:", sum(1 for r in records if r[idx["ID"]] not in {"", "null"}))
print("ids null:", sum(1 for r in records if r[idx["ID"]] in {"", "null"}))
PY

期待する状態です。

actions: Counter({'update': 58})
action types: Counter({'doc': 58})
ids set: 58
ids null: 0

これで、次回以降はresearchmap上の既存業績を更新できます。

論文CSVへの拡張

この記事では主に presentations を例にしましたが、同じ考え方で published_papers も出力できます。

uv run notion-export researchmap export-csv \
  --config config.yaml \
  --cache cache/publications.json \
  --target published_papers \
  --output outputs/researchmap_papers.csv

論文の場合は、次のNotionプロパティが使われます。

Notion researchmap
Name タイトル
Authors list 著者
Journal 誌名
Publication date 出版年月
Volume
Issues
Page ページ
DOI DOI

Original PaperReview paper は、基本的に published_papers として出力します。

Preprintをどう扱うか

プレプリントの記事ももちろん管理可能です。
arXivなどのpreprintもNotion DBに入れる場合、researchmap上では misc として出力します。

Notion側では、例えば次のプロパティを使います。

プロパティ 用途
Type Preprint
Journal arXiv
DOI DOIがあれば
arXiv ID arXiv ID
arXiv URL arXiv URL
Journal Status preprint, under_review, published など
Related Journal Paper 査読済み版との対応

出力時には、Preprintmisc に対応させ、misc_type = technical_report として扱います。

Preprint -> misc
misc_type -> technical_report

査読済み論文になった場合は、PreprintとOriginal Paperを別レコードとして残し、Related Journal Paper で紐づけると管理しやすいです。

ハマりどころ

actionが空で怒られる

researchmap CSVでは、業績CSVに アクション名 が必要です。

CSVの先頭列が空になっていると、インポート時にエラーになります。

対策として、Researchmap ID の有無に応じて、次のように自動出力します。

Researchmap IDなし -> insert / merge
Researchmap IDあり -> update / doc

未設定は空欄ではなくnull

researchmap CSVでは、未設定項目に空欄ではなく null を入れる必要があります。

通常のCSV感覚で空欄にすると、意図しない挙動やエラーの原因になります。

IDなしで毎回insertすると危険

Researchmap ID なしで毎回 insert / merge すると、既存業績との類似判定に依存します。重複やエラーの原因になりやすいので、初回登録後はresearchmap export CSVからIDを回収し、Notionに書き戻すのが安全です。

国コードがnullになる

国内学会は JPN と自動補完できますが、国際会議の国コードは手入力した方が安全です。

Country Code に次のような3文字コードを入れます。

USA
CAN
SGP
AUS
DEU
IRL
ITA

Notion側の値はすべて埋めなくてよい

Researchmap Type, Language Code, Visibility, Major は、空欄でも多くの場合は自動補完できます。

一方で、Sync to Researchmap, Country Code, Invited は人間が判断して入れる方が安全です。

通常の運用まとめ

初回

1. Notionに業績を入力
2. Sync to Researchmap をチェック
3. Country Codeなど必要項目を入力
4. fetch
5. researchmap CSVを生成
6. researchmapにアップロード
7. researchmapからCSVをエクスポート
8. match-csvで照合
9. sync-idsでResearchmap IDを書き戻す

次回以降

1. Notionを更新
2. fetch
3. researchmap CSVを生成
4. update/doc/ID指定のCSVをresearchmapにアップロード

この運用にすると、researchmap側で直接業績を編集する必要がかなり減ります。

まとめ

この記事では、Notion DBを正本としてresearchmap V2 CSVを生成・更新する運用を紹介しました。

ポイントは次の通りです。

  • Notionを正本にする
  • researchmap CSVはNotionから生成する
  • 初回は insert / merge
  • researchmap export CSVから Researchmap ID を回収する
  • 次回以降は update / doc / ID指定
  • Country Code など、一部の値はNotion側で明示しておく
  • researchmap側の編集内容は原則としてNotionへ自動取り込みしない

研究業績はWebサイト、CV、researchmapなど複数の場所で使われます。Notionを正本にしておくと、それぞれを手作業で更新する必要が減り、表記ゆれや更新漏れも抑えられます。

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?