Entity relationship in Apigee - entity-relationship

I am new to Apigee, and confused with how entity relationships work. I have one collection called artists with the following entity:
{
"artist": "",
"profileImage": "",
"genre": "",
"style": ""
}
And another called releases like so:
{
"release":"",
"artist_uuid":""
"label": "",
"format":"",
"tracks":[
{"title":""}
{"title":""}
{"title":""}
{"title":""}
]
}
I want to know how to link the two so when I select artist it can give all the releases to that artist? I hope that makes sense.

You bet. You can join these together using connections. Use POST to connect the two entities like this:
POST https://api.usergrid.com/my-org/my-app/artists/UUID/releases/releases/UUID
Then, you can access the releases of the artists like so:
GET https://api.usergrid.com/my-org/my-app/artists/UUID/releases
(Also note: You won't need the artist_uuid field in your release entity.)
You can find more information here:
http://apigee.com/docs/app-services/content/entity-relationships

You could do it one of 2 ways. One way is that you could embed your 'releases' collection inside of your 'artists' collection so that you don't have a need to 'join'. Alternatively, you could keep the 2 collections that you have and query the releases collection (programmatically) when you have the artist identified. But you can't use like a relational database and join them automatically at query time.

Related

Search Outlook Calendar Event categories for multiple hits - Microsoft Graph

I am trying to keep track of Outlook calendar events without the need to store information about them on my own systems. I decided to do this by adding the required ids as categories with their type of id before it as shown in the code sample below.
{
"#odata.etag": "",
"createdDateTime": "",
"categories": [
"ID1::abc123",
"ID2::def456"
]
}
I tried using the 'any' lambda operator and this works fine if I want to filter based on one category using the query below:
https://graph.microsoft.com/v1.0/me/events?$filter=categories/any(x:x%20eq%20'ID1::abc123')
What I need is a query that will check if an event has both ids so in this case only the events where ID1=abc123 and ID2=def456. I figured https://graph.microsoft.com/v1.0/me/events?$filter=categories/any(x:x%20eq%20'ID1::abc123')%20AND%20categories/any(x:x%20eq%20'ID2::def456') should do the trick but this keeps returning empty arrays.
Thanks in advance!
Since categories are available to the user (and this is going to look really strange in outlook), I would suggest you to use the transactionId on the events to store the external id. This will automatically deny your new event if you try to create a duplicate.
I know this isn’t the answer you were looking for, but using this solution will be much more feature proof.

Best way to store JSON data in to Core Data

I'm new to Core data and was wondering which was the best way to store a Json Data like this :
{"LG" :
{ "Nexus 5" :
{ "variant"s : [
{"model" : "Nexus 5 16gb"},
{"model" : "Nexus 5 32gb"}
]
},
},
{ "Nexus 4" :
{ "variant"s : [
{"model" : "Nexus 4 16gb"},
{"model" : "Nexus 4 32gb"}
]
},
},
}, ...... so on..
I tried storing the whole data as a NSDictionary, after making the Attribute Type "Transformable", but I encountered some errors such as NSUnknownKeyException.
I would like to store the data as NSStringand make use of some Relationships.
Can someone tell me what might be the best way to store the same and not saving the whole bunch of data as an NSDictionary?
My two cents.
Brand <-->> Model <-->> Variant
where Brand will contain LG, etc., Model will contain Nexus 4, etc. and Variant will contain Nexus 5 16GB, etc.
Brand has a to many relationships with Model. Model has a to many relationship with Variant.
Please refer to my prev answer on how to set up a to many relationship: Setting up a parent-child relationship in Core Data.
Anyway you should Apple doc and google a little bit. You can find a lot of materials out of there (e.g. Core Data from Scratch: Relationships and More Fetching).
I'd recommend reading up about Core Data and about relational databases in general, to avoid getting a design that might be absolute rubbish. The Core Data model should be at the centre of everything. That's what you need to design.
How you receive data in JSON is very secondary. Ignore JSON completely for the moment. First you need to get the database design right. Once you've got that, putting the things that are delivered to you through JSON is quite simple.
I'd have a table "Variant" which currently just has a variant with a string for the name, like "Nexus 5 16gb". Then I'd have a table "phone" with a relation to the manufacture, a string for the name, and a one-to-many relation for the "Variant". Then I'd have a table "manufacturer", with a string for the name, and a one-to-many relation for the "Phones".
best way? don't store json as a string!
translate the json into a valid object graph while parsing

Change OrgUnit type via Valence

I'm attempting to change the type of one custom orgunit to another to correct an error that was made previously.
Doing: GET /d2l/api/lp/1.4/orgstructure/6770
Results in:
{
"Identifier": "6770",
"Name": "Art",
"Code": "ART",
"Type": {
"Id": 101,
"Code": "Department",
"Name": "Department"
}
}
I then take that data and run it through PUT /d2l/api/lp/1.4/orgstructure/6770 as per the documentation however I change the data to be:
{
"Identifier": "6770",
"Path": "/content/",
"Name": "Art",
"Code": "ART",
"Type": {
"Id": 103,
"Code": "Discipline",
"Name": "Discipline"
}
}
Essentially only adding a "Path" property because it issues a 404 without it. As well as changing the type to a Discipline rather than Department. However the object returned is identical to the original without updating any of the type information.
Any suggestions to how to fix this? Deletion and recreation at this point is not a feasible option at all. Because both of these are "custom" org unit types I would imagine an update like this shouldn't be difficult.
This is an oversight in the documentation, combined with a somewhat awkward evolution of the API. The documentation has now been updated to be more clear on this situation:
The update orgunit properties call can only update the Name, Code, or Path properties of an orgunit, not it's Identifier (sensibly) or it's Type. (I do not believe there is a way to update the type of an org unit, once created, even in the Web UI for the LMS -- you likely have to create a new org unit, re-assign parent and children relationships as appropriate, and then drop the old unit.)
Unfortunately, you must provide a valid, good Path for the org unit, and the simple call to fetch a single org unit's properties won't tell you what the current one is.
If you don't already know what the path is, and should be, then you'll need to call the route to fetch back a list of org unit records, find the exact one that matches yours (by Identifier, or by matching on several properties like Code and Name), and then send back that Path dispensed in the record sent back there. (Note that you're strongly advised to scope the call to fetch back a list of org unit records by filtering on type, code, and/or name, and the call is paged, so you may have to proceed with it several times if you don't scope down the call enough, to find the particular org unit record in question.)

Querying TAFFYDB nested records

I have created a data model using TAFFYDB. Some of the fields have nested records. I am facing difficulties querying and updating the nested records.
For example:
var friends = TAFFY([
{
"id":1,
"gender":"M",
"first":"John",
"last":"Smith",
"city":"Seattle, WA",
"comp":
[
{
"id":1,
"audience":"cavern"
},
{
"id":2,
"audience":"cottage"
}
]
},
{
"id":2,
"gender":"F",
"first":"Basic",
"last":"Smith",
"city":"Seattle, WA",
"comp":
[
{
"id":1,
"audience":"bush"
},
{
"id":2,
"audience":"swamp"
}
]
}
]);
Supposing I need to update any of the comp field's audience, how will I go about it?
With regards to queries:
When you have simpler nested arrays, you should be able to select specific records using the has and hasAll methods. However, there is an open issue that states neither of these methods work correctly. There are commits but since the issue has been left open, I assume they are not 100% fixed.
For for complex nested data, like your example, the only thing I found was this old mailing list conversation talking about some sort of find method. No such method seems to exist though nor is there any mention of it in the docs.
With regards to updates:
You should be able to update the "comp" data by passing in the modified JSON that goes with it (assuming you are able to get the data out of the db in the first place) into a normal update. However, there is an open bug showing that update does not work when record values are objects. So even if you were able to query the data and were able to modify it, you wouldn't be able to update a record anyway because of the bug. You can however do a remove and an insert.
Despite what I found above, I did some testing and found that you can update files by passing in objects. So this is a quick example of how to do a simple update:
// To show what TAFFYDB looks like:
console.log(friends().stringify());
"[{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","comp":[{"id":1,"audience":"cavern"},{"id":2,"audience":"cottage"}],"___id":"T000003R000002","___s":true},{"id":2,"gender":"F","first":"Basic","last":"Smith","city":"Seattle, WA","comp":[{"id":1,"audience":"bush"},{"id":2,"audience":"swamp"}],"___id":"T000003R000003","___s":true}]"
// Get a copy of the comp file from the database for what you want to modify.
// In this example, let's get the **first** record matching people with the name "John Smith":
var johnsComp = friends({first:"John",last:"Smith"}).first().comp;
// Remember, if you want to use select("comp") instead, this will return an array of results.
// So to get the first result, you would need to do this despite there being only one matching result:
// friends({first:"John",last:"Smith"}).select("comp")[0];
// There are no nested queries in TAFFYDB so you need to work with the resulting object as if it were normal javascript.
// You should know the structure and you can either modify things directly, iterate through it, or whatever.
// In this example, I'm just going to change one of the audience values directly:
johnsComp[0].audience = "plains";
// Now let's update that record with the newly modified object.
// Note - if there are more than one "John Smith"s, then all of them will be updated.
friends({first:"John",last:"Smith"}).update({comp:johnsComp});
// To show what TAFFYDB looks like after updating:
console.log(friends().stringify());
"[{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","comp":[{"id":1,"audience":"plains"},{"id":2,"audience":"cottage"}],"___id":"T000003R000002","___s":true},{"id":2,"gender":"F","first":"Basic","last":"Smith","city":"Seattle, WA","comp":[{"id":1,"audience":"bush"},{"id":2,"audience":"swamp"}],"___id":"T000003R000003","___s":true}]"
For a better targeted query or update (something that perhaps acts like a nested query/update), you can possibly try passing in a function. If you look at the docs, there is a simple example of this for update():
db().update(function () {this.column = "value";return this;}); // sets column to "value" for all matching records
I have an example, in this case i made an update to a nested field.
To acces the data you can do like this:
console.log( JSON.stringify(
data({'id':'489'}).get()[0].review[0][0].comments
))
This is an example how it works

Mapping relationships with AFIncrementalStore

I'm in the process of integrating AFIncrementalStore into my project but I'm having a hard time figuring out how to make relationships work.
Let's say I have two models: Document and Page. A document has many pages (one-many). Each model has an inverse relationship to the other.
So I can do:
myDocument.pages
or
myPage.document
I'm trying to fetch all the pages that belong to a document. I have an AFIncrementalStore subclass and an AFHTTPClient subclass that implement the necessary methods.
I can see that the right REST URI is called (eg. /documents/:id/pages). I can also see that the pages get downloaded and stored into the pages table in the sql database.
The problem is the relationship between the two isn't made. When I look at the DB the foreign key column is empty.
Also if I do myDocument.pages it doesn't return anything.
Do I have to manually link these two when new data is fetched? I'm reading through the AFIncrementalStore source but nothing is sticking out.
Thoughts?
Alright, after a few hours or debugging and reading through AFIS line by line I got it to work, but it required some changes to the REST API.
Initially I had my API return something like the following (example):
GET /documents/12/pages
Response:
{
title: "My Title",
body: "Some body text ..."
}
But in order to make it work nicely with AFIS I had to add a reference to the Document in there, like so:
Response:
{
title: "My Title",
body: "Some body text ...",
document:
{
id: "12"
}
}
As long as in CoreData the relationship is properly setup, AFIS will loop through relationships and automatically find the relationship "document" and look for that key in the returned object. If your server key doesn't match your core data property then you can override one of the AFIncrementalStoreHTTPClient protocol methods to specify the right object.
This is working fine for now, I'll report back if something goes wrong.
Hope that helps someone else out.

Resources