2023-03-15
/icons/pass.iconやったこと
おそらく色々とややこしい
LevelRecordとSingleSegmentRecordの関係
名前が同じエンティティを果たして同一のタグとして扱っていいのか.... + メモリ容量を大幅に節約できる。メモリ空間上で無駄がない
+ 同一のデータをいくつも保持する必要がない。
- システムを理解する側の人の負担が高い
- 付加情報をつける際に、個別の作品ごとに付加情報をつけるのが難しい。
出来たとしても
- エンティティの管理IDとタグの管理IDが異なるため、混乱の元。バグが発生するかも。
....もしかしてあんまり利点がない?
やっぱりタグとエンティティは一対一対応するように扱おうか。
やっぱり草生えてる方が満足度があるよな....。
次
目標 - 17:00
開発日誌上だと、今後の変化を心配せずに実装内容を考えることができるので良い。
KSSRsで要求される仕様を実装しようとすると、少しばかり困難がある。 愚直にタグ配列(Tag[])を記録ドキュメント中ののプロパティに持たせると、検索をするときに制約に引っかかる。 array-contains
1 つのクエリで使用できる array-contains 句は 1 つだけです。
二つ以上のタグ検索が常となるこのシステムではあまりにも強い制約。
array-contains-any
渡された配列の要素を少なくとも1つ持つドキュメントを取り出してくる。
OR検索のみができる
オブジェクトのハッシュで集合を表現する。
悩んでいたところ、以下のような記事を発見した。
従来推奨されていたパターンの、オブジェクトのハッシュを配列として表現するパターンが有効かもしれない。 この表現方法が有効なのは以下の条件が満たされる場合
タグの集まりは集合とも捉えられるため、このいずれも満たす。 アクセスも、ハッシュの性質上O(1)またはO(logn)で済む。
nも高々10程度だろうから、線形探索をしてもそこまでコストにならないと判断した。
よって、オブジェクトのハッシュでタグを表現する。
先んじて、以下のように定義する。
ID<T>を、データ構造Tのプロパティidの型とする。
code:ts
type ID<T> = T extends { id: infer V } ? V : never;
https://gyazo.com/52db356ce117886f7aad4a868bc02e4c
code:ts
また、配列にはオブジェクトのハッシュを使えば良い。
よって、以下の通りに策定する。
本来の推奨パターンで値にtrueを入れていたが、ここではタグ種別の情報を入れ込むことにした。 こうすることで、タグのID-日本語翻訳などを高速化できる。
code:ts
interface LevelRecordDocument{
id: string;
score: number;
docinfo: DocumentInfo;
parent_single_segment_record?:ID<LevelRecord>[];
}
しかも、このプロパティにおいては複数のarray_containsをAND検索する機会はないため、この形式で保存する。
code:ts
interface SingleSegmentRecordDocument{
id: string;
tags: Set_of_Tag;
score: number;
level_records:
(ID<LevelRecord> | ID<SingleSegmentRecordDocument>)[];
scores: number[]
docinfo: DocumentInfo;
}
code:ts
interface GameTitleDocument{
id: string; //エンティティに対して与えるID
tagID: ID<Tag>; // 対応するタグのID
rule: string;
record_count: number;
runners_list: Set_of_Tag;
score_type: ScoreType;
}
他に必要な情報がないため、現状は用意しない。
しかし、このデータは
全ての名前情報をここで管理する。
code:ts
interface TagDocument{
id: TagID
kind: TagKind;
default_name: string;
game_title?:ID<GameTitleEntity>;
actual_name?: ActualName;
}
code:ts
場合わけが必要。
ただ単純にAbility#Bombとした場合、それは複数のエンティティを指している。