Knowledgeのランキングに納得いかねぇので評価軸を暴いてやった話 ～後編～

　

[SC（非公式） Advent Calendar 2018](https://qiita.com/advent-calendar/2018/unofficial-sc) の三日目になります。
本記事は [Knowledgeのランキングに納得いかねぇので評価軸を暴いてやった話 ～前編～](https://qiita.com/wryu/private/11ba929ef902e59db200) の続きです。

# 前回のあらすじ
所属部署内で「KnowledgeShareシステム」なるWeb投稿型の知識共有プラットフォームが開設されたものの、
その中にある記事の人気ランキングのページ内容は "人気" と評価するロジックが不透明なうえに
在るべき姿と実態がかけ離れているものになっていた...。

義憤を覚えたジェダイ、wryuはそれがOSSを利用したアプリであることを知り、
OSSの大元のサイトからGitHubの当該リポジトリに辿り着き、単身、zipを落として解析を始めたのであった...

　

はい、ということでSW風フライングあらすじをして満足したところで、さっそく再開します。

# 3. 調査(資料編)
### 頭の中で考えたこと
情報が辿れそうなところまでは来たので、あとは資料とソースを見ていきます。
ここまで来たら詰むまで調査あるのみです。

### やったこと
KnowledgeのTOPページにあった画面右上の「Download」のリンクを辿って本体を落としてみます。

![GitHub遷移先](https://qiita-image-store.s3.amazonaws.com/0/131674/008f172e-2253-a3d7-e5e3-c8bbd27f13c7.png)

　
GitHubのページに飛びました。
.warファイルが含まれているので、どうやらJavaで開発されているようです。
また、ソースコードも含まれているようですので、最悪ソースから仕様を読み取れば大丈夫そうです。
(幸い、筆者にとってJavaは開発経験のある言語でした)

ではGithubの当該リポジトリのTOPページに移って、丸ごとzipで落としてみます。
(割愛)
　

はい、解凍したのがコチラです。
(図1)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/131674/02c30b66-10b8-076b-da72-7f9c79ffc419.png)
srcフォルダにソースも入っており、なんと丁寧に関連ドキュメントの入ったdocumentフォルダまで含まれています。

まずは仕様や設計資料があることを願ってdocumentフォルダから見ていきます。
見たところ下のような階層になっていました。

```
documentフォルダ
┗―+ databaseフォルダ
　┗― A5M2_knowledge.pdf
　┗― A5M2_web.pdf
　┗― knowledge.a5er
　┗― web.a5er
┗―+ imagesフォルダ
　┗― icon.png
　┗― startup-594090_640.jpg
　┗― startup-594090_1280.jpg
　┗― startup-594090_1920.jpg
┗―+ sampleフォルダ
　┗―+ logフォルダ
　　┗― default-logging.properties
　　┗― log4j.xml
　　┗― logging.properties
```

どうやらワード/エクセルで書かれた仕様書や設計書のようなものは含まれていないようです。

が、よく見るとdatabaseフォルダの中にa5erファイルが含まれています。
a5erファイルというのは[A5:SQL Mk-2](https://a5m2.mmatsubara.com/)という素晴らしいdatabaseフリーツール上で作られるER図のファイル形式です。
ってことはこれがアプリのER図ってことですね。

まずは「A5M2_knowledge.pdf」から見てみましょう。
<img width="500" alt="A5M2_knowledge" src="https://qiita-image-store.s3.amazonaws.com/0/131674/fa68bce0-9d19-20af-b4b9-3b49f2d59469.jpeg">

う～ん、ざっと見渡しても「いいね」とかはあるものの、「ハート」にあたるような文言がない、、
あと投稿される記事のことは「ナレッジ」という表記で書かれているようです。

ということで1記事に関する情報を探るべく、「ナレッジ」のエンティティを見てみましょう。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/131674/09988db4-0d17-373e-45e7-42f58a4d9973.png)

怪しいのがありますね。「ポイント」という属性がなんとなく香ばしいです。
ER図上右の方を見ていくと「ナレッジのポイント獲得履歴(POINT_KNOWLEDGE_HISTORIES)」や
「ユーザのポイント獲得履歴(POINT_USER_HISTORIES)」といったものがあります。
他に "いいね件数"、"参照件数"、"コメント件数" といった属性があることを見ても
こいつが激臭です。

他にもエンティティはありますが具に見ていくとキリがないので、
この「ポイント(POINT)」属性にフォーカスを当てて探っていきましょう。



# 4. 調査(ソースコード編)
### 頭の中で考えたこと
資料はこれ以上なさそうなので、DBのKNOWLEDGEテーブルのPOINTカラムに焦点を当ててソースを見ていきます。
OSSとしてのKnowledgeアプリがどのようなJavaフレームワークに則って開発されているかはわかりませんが、
どんなフレームワークでもDBへつながるDataAccessレイヤはあるはずです。

そこで、SQLそしてDataAccessレイヤから、ポイントを算出しているビジネスロジックを含めた
サービスクラスにたどり着くことを目標にします。

### やったこと
zipを展開した図1のフォルダにある通り、srcフォルダを対象に「POINT」を検索語句に据えて適当なツールでGREPします。
(今回はサクラエディタを使用)
※GREP・・・テキストファイル中から、正規表現に一致する行を検索して出力するコマンド
[GREPとは(Wikipedia)](https://ja.wikipedia.org/wiki/Grep)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/131674/3cbcb3bf-40cc-5c09-04cc-0a73d9ed4933.png)

957個...ちょっと多いですね。。

ざーっとスクロールしていったところ、途中気になるところがありました。

```
 (アドレス割愛)\src\main\java\org\support\project\knowledge\logic\KnowledgeLogic.java(253,32)  [UTF-8]:
                   data.getKnowledge().setPoint(db.getPoint()); // ポイントもDBの値を引き継ぐ
```


丁寧に日本語でコメントがなされている、、
なんとなくGitHubに投稿するようなOSSって外国向けに日本語のコメントは残さない、みたいな感じかと思ったら
Knowledgeについてはガッツリ開発時のコメントが残されているようです。
(なんか親近感が湧きました)

　

ということは、これは「ポイント」でソース上のコメントを検索した方がよいのでは...！？



![image.png](https://qiita-image-store.s3.amazonaws.com/0/131674/a046af24-d4f2-c35e-e745-84d761e74845.png)
196個！イイ感じに減りました！
しかも思いっきり仕様が説明として書かれている！これはもう勝ち確ですね。


　
　

そして流し読みしていったところ、探し求めていた答えが

> src\main\java\org\support\project\knowledge\logic\activity\Activity.java

に冒頭のクラスの説明コメントとして、バッチリ記述されていました！！



　
　

それがこちら

```
/**
 * ポイントが増減するアクティビティの種類
 * 
 * 種類  | ターゲット文字列 | イベントの内容
 * 1    | knowledge_id  | 記事を登録(使わない）
 * 2    | knowledge_id  | 記事参照
 * 3    | knowledge_id  | 記事へイイネを登録
 * 4    | knowledge_id  | 記事をストック
 * 5    | knowledge_id  | アンケート回答
 * 6    | knowledge_id  | イベント参加
 * 10   | knowledge_id  | 記事を「公開」で投稿（登録／更新時）→増える
 * 11   | knowledge_id  | 記事を「保護」で投稿（登録／更新時）→前が非公開であれば増える、前が公開であれば減る
 * 12   | knowledge_id  | 記事を「非公開」で投稿（登録／更新時）→前が「公開」「保護」の場合減る（前が「公開」「保護」で無い場合登録しない/非公開の記事ではポイント増えない）
 * 101  | comment_no    | コメント登録
 * 103  | comment_no    | コメントにイイネ登録
 * -6   | knowledge_id  | イベント参加の取り消し
 * 
 * ---------------------------------------------------------------------------
 * 
 * ポイント操作
 * 
 * 種類  | 獲得のタイプ  | ポイント付与先 | ポイント    | 獲得タイプの意味
 * 1    | 11          | 記事登録者    | 50       | 記事を投稿したら投稿者にポイント追加(使わない）
 * 1    | 13          | 記事         | 50       | 登録された記事のポイント初期値(使わない）
 * 2    | 21          | 参照者       | 1        | 記事を参照するアクションを行うと、参照者にポイント追加（一つの記事に付き1回のみ）
 * 2    | 22          | 記事登録者    | 1        | 自分が登録された記事が参照されたら、登録者にポイント追加（一つの記事に対し、参照者毎に1回のみ）
 * 2    | 23          | 記事         | 1        | 記事が参照されると、その記事のポイントが追加（一つの記事に対し、参照者毎に1回のみ）
 * 3    | 31          | 参照者       | 2        | 記事にイイネのアクションを行うと、参照者にポイント追加（一つの記事に付き1回のみ）
 * 3    | 32          | 記事登録者    | 10       | 自分が登録された記事にイイネがついたら、登録者にポイント追加（一つの記事に対し、参照者毎に1回のみ）
 * 3    | 33          | 記事         | 10       | 記事が参照されると、その記事のポイントが追加（一つの記事に対し、参照者毎に1回のみ）
 * 4    | 41          | 参照者       | 0        | ストックした場合、ストックした人にポイントは付与しない
 * 4    | 42          | 記事登録者    | 2       | 記事の登録者にポイント追加（一つの記事に対し、参照者毎に1回のみ）
 * 4    | 43          | 記事         | 2       | 記事のポイントが追加（一つの記事に対し、参照者毎に1回のみ）
 * 5    | 51          | 参照者       | 3        | アンケート回答者にポイント付与
 * 5    | 52          | 記事登録者    | 3       | 記事の登録者にポイント追加（一つの記事に対し、参照者毎に1回のみ）
 * 5    | 53          | 記事         | 3       | 記事のポイントが追加（一つの記事に対し、参照者毎に1回のみ）
 * 6    | 61          | 参照者       | 5        | イベント参加者にポイント付与
 * 6    | 62          | 記事登録者    | 5       | 記事の登録者にポイント追加（一つの記事に対し、参照者毎に1回のみ）
 * 6    | 63          | 記事         | 5       | 記事のポイントが追加（一つの記事に対し、参照者毎に1回のみ）
 * 10   | 101         | 記事登録者    | 50       | 公開になった時点でトータル50になるように
 * 10   | 103         | 記事         | 50       | 
 * 11   | 111         | 記事登録者    | 30       | 
 * 11   | 113         | 記事         | 30       | 
 * 12   | 121         | 記事登録者    | 0        | このアクティビティの前に、投稿のアクティビティがあった場合、それを打ち消す（マイナスのポイント）
 * 12   | 123         | 記事         | 0        | 
 * 101  | 1011        | 登録者       | 20       | コメントを投稿すると、投稿者にポイント追加
 * 101  | 1013        | 記事         | 20       | 記事にコメントが付くと、その記事に対しポイント追加
 * 103  | 1031        | 参照者       | 2       | イイネを押すと、押した人にポイント追加
 * 103  | 1032        | 登録者       | 10       | コメントにイイネが付くと、そのコメントを登録したユーザにポイントが付く
 * 103  | 1033        | 記事         | 10       | コメントにイイネがつくと、そのコメントの記事に対しポイント追加
 * -6   | -61         | 参照者       | 5        | イベント参加者にポイント付与（取り消しなのでマイナス）
 * -6   | -62         | 記事登録者    | 5       | 記事の登録者にポイント追加（取り消しなのでマイナス）
 * -6   | -63         | 記事         | 5       | 記事のポイントが追加（取り消しなのでマイナス）
 * 
 * ユーザのポイントは、USER_CONFIGSテーブルへ格納する
 * ポイントはランダムで少し増減した方が面白い？？
 * ポイントは、だいたいの定義で、各実装の処理内で拡張する（例えば、イイネは、件数が増える毎に、ナレッジに付くポイントは増加するとか）
```

　
思っていたよりめちゃくちゃ細かい、、
これはポイントにまつわるマニュアルを作らないのも頷けますね。
おそらくこれらを総合してポイントの総計を算出するロジックがあるのだと思いますが
これを見たらもうどうでもよくなっちゃいました。

とにかく、「人気」と判断されるのは記事の参照、イイネ、コメント、記事のストックなんかが関係あるようです。
弊社で展開されているシステムで議事録とかが「人気扱い」となってしまうのも納得ですね。
(特にコメントは20ポイントと、後付けで付与できるポイント数としてはかなり高いですし)


そして、↑の仕様を見る限り、デフォルトの状態で結構細かい点まで考慮されて設計されているようです。
弊社で展開されているものにさらに手が加えられている可能性もなくはないですが、
むしろ問題があるとすれば、個人の記事と議事録や仕様のメモ書きといった業務のドキュメントを
一括で同じ場で投稿/管理しようとする利用方法にあるのかもしれません...。

　

・・・
　
　
ということで、なんだかスッキリしない感じになってしまいましたが
社内システムという出発点から、結局社内関係ないOSSのソースを見る旅となったものの、これで目的は達成されました！
(投稿者のモチベーションを上げるアイデアの創出と、ランキングの内容がおかしいのは結局そのままですけど)

# 5. 終わりに
いかがでしたでしょうか。
体系立てた方法論等では全くなかったですが、私は大体訳の分からん問題にぶち当たったら
こんな感じで問題を解決すべく電子の海を泳いでいます。

あと書き終わってみて思いましたが、これ二回に分ける量でもなかったですかね。。
(カレンダーの枠を潰してしまってスミマセン)

とにかく、これを読んでいる若手の皆さんが、訳の分からん調査タスクが実業務で振られた時に
少しでも解決やその為のアプローチのヒントになれば幸いです。