diff options
Diffstat (limited to 'devdoc')
-rw-r--r-- | devdoc/viewer_index_v2.1.md | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/devdoc/viewer_index_v2.1.md b/devdoc/viewer_index_v2.1.md new file mode 100644 index 0000000..c37e925 --- /dev/null +++ b/devdoc/viewer_index_v2.1.md | |||
@@ -0,0 +1,156 @@ | |||
1 | --- | ||
2 | title: "Viewer: index v2.1" | ||
3 | author: pacien | ||
4 | date: 2022-10-22 (v2) | ||
5 | --- | ||
6 | |||
7 | # Abstract | ||
8 | |||
9 | This is a short documentation of the viewer's internal index dating from the | ||
10 | first version of this software and still currently in use in version 2.1. | ||
11 | |||
12 | This index was written without proper specifications or documentation, and has | ||
13 | evolved a lot since then. | ||
14 | |||
15 | This document is an attempt at describing how this index is currently being | ||
16 | generated and used, before further work can be done on some proper | ||
17 | specification to clarify the problematic behaviours. | ||
18 | |||
19 | |||
20 | # Document version history | ||
21 | |||
22 | 1. 2022-10-15: call notes | ||
23 | 2. 2022-10-22: rewritten | ||
24 | |||
25 | |||
26 | # Description of the current implementation | ||
27 | |||
28 | ## Generating the index(es) from the item tree | ||
29 | |||
30 | The gallery item index (`index.json`) is loaded by the `galleryStore` and made | ||
31 | available as the `galleryIndex` attribute. | ||
32 | |||
33 | Two indexes are derived from that file through the `indexFactory` service: | ||
34 | |||
35 | - `tagsIndex`: | ||
36 | - Maps each tag "part" (component) to items tagged with it. | ||
37 | - Maps the left-most disambiguating component to all components on its right. | ||
38 | - Includes a normalised version of the tag for searching. | ||
39 | - (Stores the left-most `rootPart` component. This is not used anywhere). | ||
40 | |||
41 | - `tagsCategories`: | ||
42 | - Same as `tagsIndex`, but partitioned by tag category prefixes as defined in | ||
43 | the viewer configuration. | ||
44 | |||
45 | |||
46 | ## Search query input auto-completion "suggestions" | ||
47 | |||
48 | The `TagInput` component suggests tags as the user types in that input field. | ||
49 | |||
50 | This is provided by the `indexFactory.searchTags` function in fuzzy | ||
51 | (non-strict) mode, which only uses the global tag index. | ||
52 | |||
53 | The fuzzy search is implemented as a normalised (lowercase) infix word lookup, | ||
54 | including the disambiguating tag parts. | ||
55 | |||
56 | The auto-completion suggestions are independent of the current directory. | ||
57 | Suggestions yielding no result (incompatible with the current search query) are | ||
58 | not excluded either. | ||
59 | |||
60 | |||
61 | ## Item search | ||
62 | |||
63 | The search query is stored in the URL query. This allows a search to be shared | ||
64 | by copying the current URL. | ||
65 | |||
66 | This URL search query is updated by `LayoutLeft.vue` to match modifications | ||
67 | made through the tag input or related filters "propositions". This component | ||
68 | also updates the store to match the URL query through `galleryStore.search`. | ||
69 | |||
70 | A search query consists of three sets of tags: an intersection list, a forced | ||
71 | inclusion (union) list, and a forced exclusion list. The last two are denoted | ||
72 | with a `+` and `-` modifier prefix before the tag name. The order of the terms | ||
73 | does not matter. | ||
74 | |||
75 | The result computed in `indexSearch.indexSearch` is given by | ||
76 | `(⋂(intersection) ∪ ⋃(forced inclusion)) ∖ ⋃(forced exclusion)`. | ||
77 | |||
78 | The string representation of a query is parsed in `indexFactory`. It is | ||
79 | serialised by taking the `filter.display` property of filters, in | ||
80 | `LayouLeft.vue` for being displayed in the tag input and in the URL. | ||
81 | |||
82 | |||
83 | ## Related filters "propositions" | ||
84 | |||
85 | The left pane of the user interface lists related filters "propositions", | ||
86 | related to the current search results or directory being viewed. | ||
87 | |||
88 | Tags in that pane are grouped according to the `tagCategories` gallery | ||
89 | configuration key. (This is currently buggy: some tags can appear in the wrong | ||
90 | category under some circumstances). | ||
91 | |||
92 | The related tags are filtered with respect to the current search query or | ||
93 | directory: only tags that are present on the listed items are shown. | ||
94 | |||
95 | Each "proposed" tag has an occurrence count of the items having that tag in the | ||
96 | whole gallery. (This is inconsistent with the locality of the filter). | ||
97 | |||
98 | This is computed using a full gallery search through the `galleryStore` using | ||
99 | `indexFactory.searchTags` in strict (non-fuzzy) mode. | ||
100 | |||
101 | |||
102 | # Identified issues and proposals | ||
103 | |||
104 | ## Issues affecting the end users | ||
105 | |||
106 | - Tags categories and disambiguation aren't properly defined: | ||
107 | - It is not clear whether intermediate tag components should be treated as | ||
108 | tags and suggested at all. (They currently are). | ||
109 | |||
110 | - Tags with more than two components do not seem to be handled correctly: | ||
111 | - `a:b:c`: `c` is not registered as a child of `a` in `tagsIndex`. | ||
112 | - This seems to be the cause of tags being displayed in the wrong category in | ||
113 | the suggestion pane. | ||
114 | |||
115 | - The tag input's auto-completion suggests impossible intersections: | ||
116 | - The fuzzy (non-strict) search does not work the same way as the suggestions | ||
117 | panel, which restricts the suggestions. | ||
118 | - This might however be problematic for forced inclusions (union) tags | ||
119 | which are still meaningful. | ||
120 | |||
121 | - The tag occurrence counts in the related tags "propositions" pane is | ||
122 | misleading: | ||
123 | - This view suggests only the tags for the current search results | ||
124 | (descendants of the current directory and matching the current search query | ||
125 | if any), | ||
126 | - But the occurrence count for each tag is global (on the whole gallery | ||
127 | instead of the current search results). | ||
128 | |||
129 | |||
130 | ## Issues affecting only the developers | ||
131 | |||
132 | - Ambiguous terminology: | ||
133 | - For example "index" vs "index.json", or "tag suggestions" vs | ||
134 | "tag propositions" vs "tag completion". | ||
135 | - This confusion is reflected in the component naming and coupling… | ||
136 | - A glossary and would help. | ||
137 | - Refactoring and renaming the modules would help. | ||
138 | |||
139 | - Tight coupling of the tag-related and index operations: | ||
140 | - It goes all over the place. | ||
141 | - Some concerns should and can clearly be separated for example: | ||
142 | - For example query parsing, compiling and actual run on the item tree. | ||
143 | - The new modules should make use of composition with the rest of the | ||
144 | components. | ||
145 | |||
146 | - Lack of unit tests: | ||
147 | - Coupling is preventing easy unit testing. | ||
148 | - Once the concerns are separated: | ||
149 | - We'll have clear expected outputs with respect to some input. | ||
150 | - It should be easier to do unit testing: | ||
151 | - (perhaps through randomised property testing). | ||
152 | |||
153 | - Minor: relatively verbose and intertwined imperative code: | ||
154 | - The query parsing and recursive tree operations would probably be more | ||
155 | elegant in PureScript than Javascript/Typescript. | ||
156 | - Same with unit and property tests. | ||