Closed alank64 closed 10 years ago
If it's just computed fields you're after, you could use Profile.compute(profileObject, callback)
. In your example it would be beneficial to use a module such as async to do something like this:
var async = require('async');
Profile.forUser = function(id, callback){
var cypher = "START u=node({user_id}) "
+ "MATCH u-[r2:has_profile]->p "
+ "RETURN p";
db.query(cypher, {user_id: id}, function(err, results){
if (err)
return callback(err, null);
else
return async.map(results, function(profile, callback) {
Profile.compute(profile, callback);
}, callback);
});
};
However, if you're after compositions as well, we don't have any support for that yet :( You'd have to do a Profile.read
for each object in results
.
Does this answer your question? I know model.compute
isn't documented yet, and I'll fix that. If you have a suggestion of a better API for this case, I'm totally open to it.
This works fine for me!
One suggestion, and once I get a little more experienced with node.js, would be to have...
db.query(cypher, {user_id: id}, {p: Profile}, function(err, results){...
where the 'p' would map to the RETURN values in the query. Another way would be to have a property 'class_type' in every node. Then when evaluating Cypher results, the node results could be cast into the class. Just ideas
Again, thanks for the quick response! Tested your solution above and works great.
I definitely see where you're coming from, but that API would mean tightly coupling seraph to seraph-model, and I'm not comfortable with doing that just yet. As it stands, seraph has no concept of seraph-model. And if we did do it that way, would it end up querying for compositions as well? It might be quite an overhead to add.
Something that might be a little more abstract, but a long the same lines, could be like this:
db.queryMap(cypher, {user_id: id}, {p: Profile.compute}, function(err, results) {...
But we're approaching the point here where it's simpler to just make the async.map
call in the callback and do it yourself. Unfortunately it's not as simple as casting to another kind of object - objects that you save and read with the Profile
model are semantically no different to any other javascript object. There's no way to differentiate them, and there's no way to check if an object is a Profile
or not.
I'll have a think about it and see if I can come up with any better API for this use case, I can definitely see how it would be useful. It's also difficult because we need to differentiate between cases when you want to add compositions, and when you only want the computed fields.
For now, I'd suggest sticking with using Profile.compute
, as that part of the API will not be changing.
I might just be missing something but after I perform a cypher query in my model, which returns neo4j results from my profile node, I'm just not sure how to cast these into my Profile seraph-model object. So in my model I have...
but obviously, simply returning results will not give me a Profile object with my computed fields
Profile.addComputedField()
.