generated at
関連ページが広がってきた

こんにちは
shokaiですshokai
ScrapboxというWiKiを開発しています
Nota Tech Conf 2022 Springの発表資料です


関連ページリストがprojectの外にも広がりました
双方向リンク
このページからリンクしてるページ
このページにリンクしてるページ
トラックバックの様にも使えます

当日のプレゼン動画



/shokai/Scrapbox開発プロセスから、/nishio/pMovideaに関連ページを辿る様子
色々つながって面白い
意外性がある
こんな話もしていたのか〜という
実は、色々つながり過ぎないようにもしています
今日はそのへんの工夫を話します

1つの会社で複数のprojectを使っている時も便利!
/recruitmentsales/Notaがつながっている様子
会社が成長すると、複数のプロジェクトを使い分ける必要が出てくる
例:業務委託先との連絡用project



関連ページリストとは?
[リンク] を書くと、エディタの下に表示されるページのリストのこと
このページからリンクしているページ(順リンク
このページにリンクしているページ(逆リンク
共通のリンク先を持つページ
ページA ---> 共通のリンク先 <--- ページB
[ページ名] のリンク先が存在しないページであっても、関連リンクは通る
ページA ---> 存在しないページ <--- ページB
つまり、リンク先のリンク先まで関連ページとして一望できるという事です


別カテゴリのページへのリンクが媒介となって、意外な関係性が表現される
> 「和歌山」→「みかん」、「愛媛県」→「みかん」 ならば「和歌山県」と「愛媛県」はみかんつながりになっているわけだし、
> 「増井」→「Rubyプログラミング」、「高林」→「Rubyプログラミング」 ならば「増井」⇔「高林」は意味がある。
> こういう関係は普通のハイパーテキストやWebでは考えられていない気がするのだがどうだろうか。
2005年時点での増井俊之による考察
17年前…!!!!!そんなに前から考えられていたのかteramotodaiki
子供の中学受験で地理を教えるための「勉強Wiki」というのを作ってたのでした 増井俊之
/UIPediaが意外性があって面白いshokai
論文サーベイのprojectなんだけど
論文だけではなく著者のページもある
誰が誰の弟子だとか、同僚だとか書いてある
つながりが見えてくる
夫婦関係が重要 増井俊之
普通、文献管理ツールというと「弟子」なんて書く欄はない
正規化されていないデータを色々書ける自由記述欄がつながって、人間を介して研究の流れが見えてくる
かもしれない


External links 実装までの道のり
準備が重要だったshokai

表示エリアの確保
新しい機能を追加すると、既存の機能と衝突する
機能同士のコンセプトに矛盾が生じたり
UIの置き場に困ったりする
今回はこっち
External linksは、1 hop linkと2 hop linkの間に設置したい

似たような名前のページが多すぎる時に、関連ページを折り畳む機能
表示エリアを確保する為に実装した
例: Sprint.50 Sprint.51 Sprint.52
とりあえず、末尾が連番のページが対象ですshokai
今後もうちょっと賢くなる予定
これめっちゃ便利で助かってるakixteramotodaiki
連番利用は実用的でいいですね 増井俊之
Kindleの漫画折り畳みみたいだ

何もかもリンクされたら邪魔じゃないか?
/help-jp/ブラケティングは、Scrapboxの使い方(新規projectの作成時に自動配置される)からリンクされている
全ての逆リンクを表示するとExternal linkが何十万件になる
検索範囲が広すぎてDBの負荷もヤバイ事になる
現実的なレスポンス時間で計算可能なqueryにしたいshokai
全く知らない他人のprojectを見せられてもしょうがない
public設定のprojectであっても、他人の反応に一喜一憂せず、考えを深める為に自分と向き合ってテキストを書きたい

External linksに表示されるべきなのは
自分が参加しているproject
これは当然
自分が参加していないproject
興味を持ったprojectだけに絞りたい

自分が興味を持ったprojectのリスト
緑は未読あり
そういうことだったのか!!yuiseki
テロメアと同じですshokai
検索もできる
追加・削除
projectにアクセスしたら自動的に追加
右ので削除


これでExternal linksのパーツが揃った
表示されるのは
自分が参加しているproject
watch listに入っているproject


検索の実装

1 hop linkの実装
Pageのschemaで重要なのは3つ
models/page/schema.js
const schema = { projectId: id, title: string, links: [string, string, string] } schema.index({ projectId: 1, title: 1}) schema.index({ projectId: 1, links: 1})
linksには、このページ内にあるリンク記法がリストされている
この発表資料の場合 ["External Links", "トラックバック", "リンク", "関連ページスタック"] みたいな感じ
1回のqueryで取得できる
find-1-hop-links.js
const pages = await Page.find({ $or: [ { projectId: 今見てるprojectのID, links: 今見てるページのタイトル }, // 逆リンク { projectId: 今見てるprojectのID, title: [今見てるページのlinks] } // 順リンク ] })
projectIdで検索範囲を絞る
titleとlinksを使って、1 queryで双方向リンクをまとめて取得できる

Pageのschemaに .projectLinks を追加した
models/page/schema-ver2.js
const schema = { projectId: id, title: string, links: [string, string, string] projectLinks: [string, string, string] // これを追加した } schema.index({ projectId: 1, projectLinks: 1})
projectLinksには、このページ内にある別projectリンク記法がリストされている
この発表資料の場合
["/shokai/Scrapbox開発プロセス", "/nishio/pMovidea", "/help-jp/ブラケティング"]
/:projectName/:pageTitle という形式で保存している
2つqueryを追加すると取得できる
find-external-links.js
const 検索対象projectリスト = [...projectWatchList, ...自分が参加してるprojectのリスト] const pages = await Page.find({ $or: [ { // 逆リンク projectId: { $in: 検索対象projectリスト }, projectLinks: `/${今見てるproject名}/${今見てるページのタイトル}` }, { // 順リンク projectId: projectLinksの、projectName部分 title: projectLinksの、pageTitle部分 } ] })
projectIdで検索範囲を絞る
projectLinksとtitleで、双方向リンクをまとめて取得できる
つまり1 hop linkの、検索対象projectを広げたバージョンで実装できる

負荷が高まるとしたら
検索対象のprojectが多くなりすぎて、ストレージからのmongo documentのFETCHが巨大化するケースぐらいだと思う
そういう場合は、長期間アクセスしていないprojectをwatch listの検索対象から除外すればいいかな?たぶん
まあなんとかなりそう


まとめ
関連ページリストがproject外にも広がってきた
広がりすぎてもしょうがない。つながったらうれしい範囲をコントロールする仕組みを事前に仕込んだ
検索範囲が広がったけど、現実的な計算時間で処理できるqueryを構築できた
チャンネル登録と高評価お願いします

終わりみたいになったけどまだCTO&PMPO対談がありますshokai
pastak 求人のお知らせと休憩があります