]> git.evergreen-ils.org Git - working/Evergreen.git/blob - docs/TechRef/Flattener/design.txt
087b1885cb5f6876e224b9d0d346a508a805fd6a
[working/Evergreen.git] / docs / TechRef / Flattener / design.txt
1 Deep-data Flattening Service
2 ============================
3 Mike Rylander
4 with Lebbeous Fogle-Weekley
5
6 [abstract]
7 Purpose
8 -------
9 Evergreen supplies a broad API for accessing, processing and interacting with library data.  Because of the relatively complex nature of the underlying database schema, and the flexibility required by clients when, in the simplest case, performing CRUD operations, focus has been given to providing a nearly direct view of various data source.  When, however, the verbosity or complexity of full object access gets in the way of performant or straight-forward UIs, there has been a tendency to create one-off data simplification calls targetting specific use cases.
10
11 A generalized API which accepts a simplified query structure and field mapping, calculates the required backend query, and flattens the hierarchical data returned for each top level row into a would facilitate the simplification of existing UIs and provide for new UIs based on simple, reusable components.
12
13 Overview
14 --------
15 The existing, public open-ils.fielder server will be extended with two new OpenSRF methods, contained in a separate package so that they will be reusable in a private service which does not require authentication.
16
17 These methods will be supported by code which takes simplifed cstore/pcrud search and order-by hashes and computes the full data structure required for the query.  The simplification will leverage the IDL to discover links between classes.
18
19 Underlying the simplified search grammar will be a path-field mapping structure.  This will describe the layout of fields, how they are to collapse from fleshed objects, and how the shape of both the query and result data structures should be interpreted by and presented to the caller.
20
21 Mapping Structure
22 -----------------
23 Implemented as a JSON object, each property name will represent a data element that can be displayed, filtered or sorted, and each property value will represent either a simple path (in which case it is usable for display, filtering or sorting), or an object providing the path and available uses.
24
25 Example Map
26 ~~~~~~~~~~~
27 Assuming a core class of acp:
28
29 --------------------------------------------------------------------------------
30 {
31     "barcode":          "barcode",
32     "circ_lib_name":    "circ_lib.name",
33     "circ_lib":         "circ_lib.shortname",
34     "call_number":      { "path": "call_number.label", "sort": true, "display": true },
35     "tcn":              { "path": "call_number.record.tcn_value", "filter": true, "sort": true }
36 }
37 --------------------------------------------------------------------------------
38
39 'Yes I realize that this example ignores call number prefixes and suffixes, but it's just an example.'
40
41 Based on this mapping structure simplified queries can be constructed by the caller, which will then be expanded in the flattening service to produce join and where clauses that can be used by open-ils.pcrud.
42
43 Example Query
44 ~~~~~~~~~~~~~
45 Assuming the above example map:
46
47 -------------------------------------
48 {   "tcn":   { ">": "100" },
49     "circ_lib": "BR1"
50 }
51 -------------------------------------
52
53 This example would expand to a PCrud query based on the map provided above, containing not only the complex where clause, but a join tree and the necessary fleshing structure.
54
55
56 Expanded PCrud Query
57 ~~~~~~~~~~~~~~~~~~~~
58
59 ---------------------------------------
60 {
61     "+__circ_lib_aou": {"shortname":"BR1"},
62     "+__tcn_bre":{"tcn_value":{">":"100"}}
63 }, {
64     "flesh_fields": {
65         "acp":["call_number", "circ_lib"]
66     },"flesh":1,
67     "join": {
68         "__circ_lib_name_aou": {
69             "fkey":"circ_lib",
70             "class":"aou",
71             "field":"id"
72         },
73         "__call_number_acn":{
74             "fkey":"call_number",
75             "class":"acn",
76             "field":"id"
77         },
78         "__tcn_acn":{
79             "fkey":"call_number",
80             "class":"acn",
81             "field":"id",
82             "join":{
83                 "__tcn_bre":{
84                     "fkey":"record",
85                     "class":"bre",
86                     "field":"id"
87                 }
88             }
89         },
90         "__circ_lib_aou":{
91             "fkey":"circ_lib",
92             "class":"aou",
93             "field":"id"
94         }
95     }
96 }
97 ---------------------------------------
98
99
100 API
101 ---
102
103 OpenSRF Method name: open-ils.fielder.flattened_search
104
105 Parameters:
106
107 - Authentication token (as for pcrud)
108 - IDL class
109  * e.g. "acp"
110 - Path map hash
111  * e.g. { "barcode": "barcode", "circ_lib_name": "circ_lib.name", "circ_lib": "circ_lib.shortname", "call_number": { "path": "call_number.label", "sort": true, "display": true }, "id": "id", "tcn": { "path": "call_number.record.tcn_value", "filter": true, "sort": true } }
112 - Simplified query hash
113  * e.g. {"tcn": {">": "100" }, "circ_lib": "BR1"}
114 - Simplified sort/limit/offset hash
115  * e.g. { "sort":[{"circ_lib":"desc"},{"call_number":"asc"}],"limit":10 }
116  * or {"sort":{"call_number":"desc"}}
117  * or {"sort": "circ_lib"}
118  * or {"sort": ["circ_lib", {"checkin_time": "desc"}]}
119
120 Returns:
121
122 - stream (or array, for .atomic) of hashes having the shape described in the path map
123  * e.g.  { "call_number":"PR3533.B61994", "circ_lib_name":"Example Branch 1", "barcode":"23624564258", "id":7, "circ_lib":"BR1" }
124