...
Notes | Decisions | ||
---|---|---|---|
|
More research needs to be done for the first proposed approach and need to document it in detail. |
Inconsistent response when retrieving data nodes.
When a get operation is performed on Root node xpath (/) it returns an array list containing all the data nodes under the root node xpath. But if the same operation is performed for a List Data node no array list is returned instead a 404 Not Found response is returned.
Code Block | ||
---|---|---|
| ||
/v2/dataspaces/my-dataspace/anchors/multipleTop/node?xpath=/&descendants=3 |
...
As per discussion with Daniel Hanrahan and Lee Anjella Macabuhay it was decided to change the Query for retrieveing the data nodes such that it can get all data nodes that fall under a given list. The query change is based on an internal PoC prepared by Daniel through which we can retrieve all the list items by specifying the xpath of list without impacting the performance. | Change the Query to retrieve all the list items under a given list using its xPath |
Inconsistent response when retrieving data nodes.
When a get operation is performed on Root node xpath (/) it returns an array list containing all the data nodes under the root node xpath. But if the same operation is performed for a List Data node no array list is returned instead a 404 Not Found response is returned.
Code Block | ||
---|---|---|
| ||
/v2/dataspaces/my-dataspace/anchors/multipleTop/node?xpath=/&descendants=3 |
Code Block | ||||
---|---|---|---|---|
| ||||
[ { "stores:bookstore": { "store-name": "My Bookstore", "store-owner": "James", "categories": [ { "name": "Test book", "price": 100, "stock": false, "book-category": "SciFi" } ] } }, { "stores:electronics-store": { "store-name": "My Electronics store", "category": [ { "status": true, "address": "India", "store-type": "electronics" } ] } } ] |
...
"id" | "xpath" | "attributes" | "parent_id" |
---|---|---|---|
200 | "/bookstore/categories[@book-category='Kids']" | "{""name"": ""Kids book"", ""price"": 5000, ""stock"": true, ""book-category"": ""Kids""}" | 198 |
199 | "/bookstore/categories[@book-category='SciFi']" | "{""name"": ""Test book"", ""price"": 1000, ""stock"": false, ""book-category"": ""SciFi""}" | 198 |
198 | "/bookstore" | "{""store-name"": ""My Bookstore"", ""store-owner"": ""ABC""}" | null |
Code Block | ||
---|---|---|
| ||
WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths) |
So, from the above snapshot of the fragment table, it can be clearly seen that individual list items are stored in the CPS DB and there is no data node representing the entire list. And hence when the existing query is executed it looks for the fragment with the specific xpath.
...
xpath = ANY (:xpaths) |
So, from the above snapshot of the fragment table, it can be clearly seen that individual list items are stored in the CPS DB and there is no data node representing the entire list. And hence when the existing query is executed it looks for the fragment with the specific xpath.
Now, the updated query does not look for a list data node for a given xpath (representing a list Ex: /bookstore/categories). Instead, it looks for all the fragments in the table which have a similar xpath starting with "[" and ending with ] using pattern matching.
To make it work we use a combination of LIKE and NOT LIKE keywords.
For this we make use of the LIKE keyword along with % wildcard to make use of pattern matching.
But the above query would also return fragments for xpaths like /bookstore/categories[@code='1']/books[@name="Hello"]
To avoid this scenario, we make use of NOT LIKE keyword along with the same % wildcard. and hence we have [%[% to exclude multiple opening brackets.
Code Block | ||
---|---|---|
| ||
"SELECT * FROM fragment WHERE anchor_id = :anchorId " + " AND (xpath = ANY (:xpaths) OR xpath LIKE ANY (array(SELECT concat(t, '[%') FROM unnest(:xpaths) as t))) |
So as seen in the above segment of the query, we have "AND (xpath = ANY (:xpaths) OR xpath LIKE ANY (array(SELECT concat(t, '[%') FROM unnest(:xpaths) as t)))".
Any given xpath for a list (Ex: /bookstore/categories) would become like so:
Code Block |
---|
(xpath = '/bookstore/categories' OR xpath LIKE '/bookstore/categories[%') + "AND xpath LIKE :escapedXpath||'[@%]' ESCAPE '\\' " + "AND xpath NOT LIKE :escapedXpath||'[@%[%' ESCAPE '\\'" |
And this would return 2 fragments as follows.
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| [
| |||||||
[ { "stores:bookstore": { "store-name": "My Bookstore", { "stores:bookstorestore-owner": {"ABC", "categories": [ { "name": "Test book", "price": 1000, "stock": false, "book-category": "SciFi" }, { "name": "Kids book", "price": 5000, "stock": true, "book-category": "Kids" } ], "store-name": "My Bookstore", "store-owner": "ABC" } } ] |
Here we can see that in the response we get a parent node bookstore and the list named "categories", as its child, and the list items identified by keys "SciFi" and "Kids" respectively.
...