Sails/ Waterline: Ids of associations in query result not accessible without populate - mongodb

I am to a fair degree familiar with Sails and Waterline.
Situation:
We have a Model Playlist with a many-to-many association to the Model Song on sails-mongo.
When we query for all playlists, we do not want to sideload all associated songs, we just need the ids of the associated songs so that we can load them lazily later.
When we do a populate (with Ember blueprints: populateEach()) we of course get the ids, but it takes around 1s for loading all the Playlists.
Without populate it is just around 50ms.
Complication:
After getting the results with query.exec WITHOUT populate, the ids of the associated songs are not included and not sent back to the requester.
But I can log the ids of associated records to the console via iterating over Object.keys(matchingRecord).
I can set them to a new property of the matchingRecord, all without populating.
However, I cannot explicitly set them to their property name.
Using the original property name is required for the interaction with the Ember frontend.
I tried to mess around with Object.defineProperty - no success. I guess the set/get functions are overwritten to prevent that.
Questions:
How can I make those id arrays of visible/prevent that they are hidden/removed?
Are there any other ideas from your side to maneuver around this issue?
Thank you,
Manuel

Related

How to properly access children by filtering parents in a single REST API call

I'm rewriting an API to be more RESTful, but I'm struggling with a design issue. I'll explain the situation first and then my question.
SITUATION:
I have two sets resources users and items. Each user has a list of item, so the resource path would like something like this:
api/v1/users/{userId}/items
Also each user has an isPrimary property, but only one user can be primary at a time. This means that if I want to get the primary user you'd do something like this:
api/v1/users?isPrimary=true
This should return a single "primary" user.
I have client of my API that wants to get the items of the primary user, but can't make two API calls (one to get the primary user and the second to get the items of the user, using the userId). Instead the client would like to make a single API call.
QUESTION:
How should I got about designing an API that fetches the items of a single user in only one API call when all the client has is the isPrimary query parameter for the user?
MY THOUGHTS:
I think I have a some options:
Option 1) api/v1/users?isPrimary=true will return the list of items along with the user data.
I don't like this one, because I have other API clients that call api/v1/users or api/v1/users?isPrimary=true to only get and parse through user data NOT item data. A user can have thousands of items, so returning those items every time would be taxing on both the client and the service.
Option 2) api/v1/users/items?isPrimary=true
I also don't like this because it's ugly and not really RESTful since there is not {userId} in the path and isPrimary isn't a property of items.
Option 3) api/v1/users?isPrimary=true&isShowingItems=true
This is like the first one, but I use another query parameter to flag whether or not to show the items belonging to the user in the response. The problem is that the query parameter is misleading because there is no isShowingItems property associated with a user.
Any help that you all could provide will be greatly appreciated. Thanks in advance.
There's no real standard solution for this, and all of your solutions are in my mind valid. So my answer will be a bit subjective.
Have you looked at HAL for your API format? HAL has a standard way to embed data from one resources into another (using _embedded) and it sounds like a pretty valid use-case for this.
The server can decide whether to embed the items based on a number of criteria, but one cheap solution might be to just add a query parameter like ?embed=items
Even if you don't use HAL, conceptually you could still copy this behavior similarly. Or maybe you only use _embedded. At least it's re-using an existing idea over building something new.
Aside from that practical solution, there is nothing in un-RESTful about exposing data at multiple endpoints. So if you created a resource like:
/v1/primary-user-with-items
Then this might be ugly and inconsistent with the rest of your API, but not inherently
'not RESTful' (sorry for the double negative).
You could include a List<User.Fieldset> parameter called fieldsets, and then include things if they are specified in fieldsets. This has the benefit that you can reuse the pattern by adding fieldsets onto any object in your API that has fields you might wish to include.
api/v1/users?isPrimary=true&fieldsets=items

Making unique reproducible ids based on strings (for mongoose model)

I pull data (a list of properties) from a city's website and it contains info like address, property owner, and longitude and latitude.
I need to make a unique id out of this and the properties will be stored in a database. The id needs to be reproducible because I will be checking occasionally to see if there are new properties so the only way to cross compare is by being able to make the id on the spot.
Is this a common problem to run into when pulling data and checking if there is anything new? I am using mongoose as the database and I am not sure if a non relational database is the best solution for my problem but I know I can make it work.
The current plan is to just combine longitude and latitude and call that the unique id. The city's data unfortunately doesn't have any unchanging unique id so I have to hack something together for comparing their data to what I have saved in the database.
Any ideas on what a better less hacky method is? Does mongoose have a different way to deal with this?

Storing custom temporary data in Sitecore xDB

I am using Sitecore 8.1 with xDB enabled (MongoDB). I would like to store the user-roles of the visiting users in the xDB, so I can aggregate on these data in my reports. These roles can change over time, so one user could have one set of roles at some point in time and another set of roles at a later time.
I could go and store these user-roles as custom facets on the Contact entity, but as they may change for a user from visit to visit, I will loose historical data if I update the data in the facet every time the user log in (fx. I will not be able to tell which roles a given user had, at some given visit).
Instead, I could create a custom IElement for my facet data, and store the roles along with a timestamp saying when the given roles were registered, but this model may be hard to handle during the reporting phase, where I would need to connect the interaction data with the role-data based on timestamps every time I generate a report.
Is it possible to store these custom data in the xDB in something else than the Contact collection? Can I store custom data in the Interactions collection? There is a property called Tracker.Current.Session.Interaction.CustomValues which sounds like what I need, but if I store data here, will I be able to perform proper aggregation/reporting on the data? Any other approaches I haven't thought about?
CustomValues
Yes, the CustomValues dictionary is what I would use in your case. This dictionary will get serialized to MongoDB as a nested document of every interaction (unless the dictionary is empty).
Also note that, since CustomValues is a member of the base class Sitecore.Analytics.Model.Entity, this dictionary is available in many other data classes of xDB. For example, you can store custom values in PageData and PageEventData objects.
Since CustomValues takes an object of any class, your custom data class needs some extra things for it to be successfully saved to and subsequently loaded from MongoDB:
It has to be marked as [Serializable].
It needs to be registered in the MongoDB driver like this:
using Sitecore.Analytics.Data.DataAccess.MongoDb;
// [...]
MongoDbObjectMapper.Instance.RegisterModelExtension<YourCustomClassName>();
This needs to be done only once per application lifetime - for example, in an initialize pipeline processor.
Your own storage
Of course, you don't have to use Sitecore's API to store your custom data. So the alternative would be to manually save data to a custom MongoDB collection or an SQL table. You can then read that data in your aggregation processor, finding it by the ID of currently processed interaction.
The benefit of this approach is that you can decide where and how your data is stored. The downside is extra work of implementing and maintaining this data storage.

How to avoid retrieving objects that are already retrieved in Parse?

I'm making an app that are retrieving messages as PFObjects with Parse, and I retrieve these messages in my viewDidLoad-function. The problem is that this function retrieves the messages every time the page is loaded.
So I thought about making a list in my core data where I save all the id's of my already retrieved objects, and then compare the id of the newest(and possibly already retrieved) object that is being retrieved to the ones in this list.
Because I don't wanna use core data unnecessary, I was just wondering if anyone had a other and more efficient solution to this problem.
Any suggestions would be highly appreciated.

Accessing a class that is related to two other classes

Given the following tables: User, Trial, UserTrial. Where A user has multiple trials, a Trial does not internally map to any Users and contains details about the trial (name, description, settings), and a UserTrial contains information specific to an instance of a User's trial (expiration date, for example). What would be the proper way for the controller of an MVC application to access data about a UserTrial?
Additional Details
There is no ORM
Each class is dual-purposed to be useable to create new, or load existing Users, Trials, or UserTrials. The constructor loads data when passed an ID and persists it with the method ->save()
It would seem that there are 2 options:
1
User.SetTrial()
User.GetUserTrial()
2
UserTrial.SetUser()
UserTrial.SetTrial()
UserTrial.GetSomeData()
Which is the most appropriate usage?
I don't think your option 1 will work because if each User can have multiple Trials, then you'd need something like User.AddTrial(Trial), User.RemoveTrial(Trial), User.getUserTrails().
Which design option you choose depends on whether you want to make UserTrial objects "first class" or not. Do you want to consider Users and Trials to be the primary objects with UserTrial objects just glue to hold the relations, or do you want UserTrial objects to be primary as well? If the former, you'll want something like your option 1; if the latter, you'll want something like your option 2.