Node-Neo4j How to check if node exists(persistently)? - neo4j

I'm using Node-Neo4j client for my db. I want to create unique node, but I couldn't find how to do that in the documentation of Node-Neo4j. I used the logic below to check if a node exists or not:
person_param = {'name': namesurname, 'userid': userid };
person_node = db.createNode(person_param);
if (!person_node.exists){
person_node.save(function(err, result){
//if(err) and if(!err) stuff
});
}
But, from what I understand, createNode creates a new node from scratch, and when I use exists on it, it just checks if the newly created node saved into database or not.
How can I check if a node with supplied properties already exists in db or not?
Thanks in advance.

The only solution I can think of, is the following:
Create your properties object
Query the Neo4J instance for those properties
If a result is returned use that
otherwise save it
In code:
var person_param = {'name': namesurname, 'userid': userid };
// Build a Cypher query
var query = [
'MATCH (user: {name: {name}, id: {userid}})',
'RETURN user'
].join('\n');
// use your params in the query
var params = person_param;
// Send the Cypher query
db.query(query, params, function (err, results) {
if (err) throw err;
// no node with such properties found
if(!results.length){
saveNode(params, callback)
} else {
// carry on with your code...
}
});
function saveNode(person_param, callback){
var person_node = db.createNode(person_param);
person_node.save(function(err, result){
//if(err) and if(!err) stuff
// call the callback here
});
}
The downside of this approach is that you need to build a Cypher query for each type of node you have, because there's no way (as far as I know) to pass both properties name and values to Cypher.

Related

SAPUI5 OData V2 Batch Operations with multiple differed groups

I'm trying to do a batch operation with multiple groupids in a single batch request. and need to get results in two different batch responses.
But when I initiate the request only one group has been submitted and only get one batch response.
Here is my code
oModel = this.getOwnerComponent().getModel("mymodel");
$.sap.itemArray.forEach(function (entry) {
if (p < $.sap.itemArray.length) {
var oData = {
"AUTO_ID": entry.Id,
"VALUE": entry.Value,
};
mParameters.groupId = "createGroup1";
oModel .create("/Table1", oData, mParameters);
}
p++;
});
for (p = 0; p < $.sap.itemArray2.length; p++) {
var oData = {
"Item2ID" : $.sap.itemArray2[p].ItemsId,
"Value" : $.sap.itemArray2[p].Value
};
mParameters.groupId = "createGroup2";
oModel .create("/Table2", oData, mParameters);
}
oModel.setDeferredGroups(["createGroup1","createGroup2"]);
oStyleSizeModel.submitChanges({
success: function(recievedObject){
var responses = recievedObject.__batchResponses;
},
error: function (oError) {
var oBody = oError.responseText;
}
});
Here is the response I got.
And here it only execute the first group's requests and only returned one batch response.
How to execute multiple batch requests with different group Ids and get each group's responses.
I believe you want to group each change separately. You need to use the concept of Change Set (not Group).
Use createEntry method instead of create.
For each call, use different changeSetId, but same groupId.
Call submitChanges passing the groupId.

Electron Nedb findOne returns null?

I am calling a simple query with findOne, so far the data in users.db is:
{"id":40, "is_admin":1,"name":"John Smith"},
{"id":43, "is_admin":1,"name":"Laura Smith"}
// Users
var users = new Datastore({ filename: 'db/users.db' });
var id_user = 43;
console.log("-------------geting users db");
//
users.loadDatabase(function (err) {
console.log("------------- users db loaded--", id_user);
// find user by id
users.findOne({ id: id_user }, function (err, a,b,c) {
console.log(a,b,c); // displays null undefined undefined
});
});
Any idea why is returning null?
I think function being passed in findOne should take 2 parameters. First parameter will be the result of query and
second parameter will be error if something goes wrong . First parameter will be Null if there is no match in db .otherwise it should return the match result.
Function(result, error ){
}
It will be you function prototype
I tested your code in my app
db.findOne({ "c2cId":"292" }, function (err, a,b,c) {
console.log(a,b,c);
});
It return one doc and undefined, undefined.
If you use findOne I guess you just want to find the first doc, so looking at the
doc at
You can see there is only two parameters err and the doc
Concerning the null: in your query are you using a variable named id? or is it the key, in last case you should use quotes....

Sending Parse Push with Cloud Code

I cannot find any documentation on Parse.Push used in Parse Cloud Code. The usage case that I see is like this...
// Send the push notification to results of the query
Parse.Push.send({
where: pushQuery,
data: {
alert: message
}
}).then(function() {
response.success("Push was sent successfully.")
}, function(error) {
response.error("Push failed to send with error: " + error.message);
});
What I am trying to do is send a push notification if a recipient user is setup for notifications (i.e. has a valid Installation instance, associated to their user).
At the moment I create the query and pass that into the above with pushQuery. What I notice is that a Push is created in the Parse dashboard but the Pushes sent is 0.
Really I just want to create the Push if a user exists. I have created the query and can run this and return if I get results or not like this...
Parse.Cloud.define("sendTurnNotificationToUser", function(request, response) {
var senderUser = request.user;
var recipientUserId = request.params.recipientId;
var message = request.params.message;
// Validate the message text.
// For example make sure it is under 140 characters
if (message.length > 140) {
// Truncate and add a ...
message = message.substring(0, 137) + "...";
}
// Send the push.
// Find devices associated with the recipient user
var recipientUser = new Parse.User();
recipientUser.id = recipientUserId;
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("user", recipientUser);
pushQuery.find({
success: function(results) {
response.success("push user lookup was ok");
response.success(results);
},
error: function() {
response.error("push user lookup failed");
}
});
I could add the Parse.Push.send call to the success of the query. However the Parse.Push.send has a where clause and I do not know what is required there? I do not want to run the query twice.
You're on the right track. Push "advanced targeting" allows the app to push to installations resulting from a query. That's what the where clause is for...
// don't run find on the pushQuery. set it up as you have it
// then, assuming it returns some installation(s)...
Parse.Push.send({ where: pushQuery, data: "hello" }).then(function(result) {
response.success(result);
}, function(error) {
response.error(error);
});
Incidentally, you can use createWithoutData on Parse.User as a shortcut ...
var recipient = Parse.User.createWithoutData(request.params.recipientId);
but the longer form you have should work, too.
It seems like you may be overthinking this. There's no harm in sending a push notification to 0 installations as the push query will not match any recipients. I wouldn't worry too much about this and I wouldn't add such a pre-check to your code. It would add an unnecessary delay to your code and of course would result in the query being run twice.
If you want to do this anyway -- maybe you wish to keep your push logs free of clutter - you can indeed query over the Installation class to check if the query would have matched a set of installations, and if it does, you can then pass that same query to Parse.Push.send().
Yes, that will result in the query run twice, but that's to be expected, as you can't know how many objects will be matched without running the query.

Returning multiple Parse classes in one PFQuery?

I currently have my parse classes set up as follows
User - objectid, usename, password, location
Profile - birthday, weight, height, et....
Settings - user app preferences such as "Show my location"
Both profile and settings have a pointer to the user objectid called "user"
Is there anyway I can call a query knowing the Users.objectid that returns both Profile and Settings?
I have played around with includes key and matches query but only get back empty results.
If it isn't possible is there a way to execute a function once both queries have completed? (using getFirstObjectInBackgroundWithBlock)
Any help would greatly be appreciated.
No, but you could hide the combination in a function....
function profileAndSettingsForUser(user) {
var profiles;
var profileQuery = new Parse.Query("Profile");
profileQuery.equalTo("user", user);
return profileQuery.find().then(function(result) {
profiles = result;
settingsQuery = new Parse.Query("Settings");
settingsQuery.equalTo("user", user);
return settingsQuery.find();
}).then(function(settings) {
return profiles.concat(settings);
});
};
You could even locate that function in the cloud, so to hide the combination from the client.
Parse.Cloud.define("profileAndSettingsForUser", function(request, response) {
// we could pass a userId in params, then start by querying for that user
// or, if we know its always the current user who's calling for his own profile and settings...
var user = request.user;
profileAndSettingsForUser(user).then(function(profileAndSettings) {
response.success(profileAndSettings);
}, function(error) {
response.error(error);
});
});

Executing Local Query with loaded metadata fails

I'm new to breeze, this looks like a bug, but thought I'd ask here in case I just don't get it.
Setup loading metadata:
var metadataStore = new breeze.MetadataStore();
metadataStore.importMetadata(metadata);
queryOptions = new breeze.QueryOptions( {
fetchStrategy: breeze.FetchStrategy.FromLocalCache
});
mgr = new breeze.EntityManager({
serviceName: 'breeze',
metadataStore: metadataStore,
queryOptions: queryOptions
});
Executing local query explicitly works:
var q = breeze.EntityQuery.from("Boards")
.toType('Board')
.where('isImplicit', 'equals', withImplicits)
.orderBy('name');
return manager.executeQueryLocally(q) // returns result
But using query.using doesn't:
var q = breeze.EntityQuery.from("Boards")
.toType('Board')
.where('isImplicit', 'equals', withImplicits)
.orderBy('name');
q = q.using(breeze.FetchStrategy.FromLocalCache)
return manager.executeQuery(q)
UPDATE: To clarify, the above throws an error as it tries to fetchMetdata and there is no endpoint to fetch from. If I monkey patch the code below, it works fine. It seems like if the dataService .hasServerMetadata, you don't need to fetch it. I'm creating a test harness for a breeze adapter, so I want to be able to run without the backend
Looks like problem is this line in EntityManager:
if ( (!dataService.hasServerMetadata ) || this.metadataStore.hasMetadataFor(dataService.serviceName)) {
promise = executeQueryCore(this, query, queryOptions, dataService);
} else {
var that = this;
promise = this.fetchMetadata(dataService).then(function () {
return executeQueryCore(that, query, queryOptions, dataService);
});
}
I believe line should be if( dataService.hasServerMetadata || ..., but being new to Breeze thought I'd ask here before opening GH issue.
EntityManager.executeQueryLocally is a synchronous function and you can use its result immediately. i.e.
var myEntities = myEntityManager.executeQueryLocally(myQuery);
Whereas EntityManager.executeQuery is an asynchonous function ( even if the query has a 'using' call that specifies that this is a local query). So you need to call it like this:
var q2 = myQuery.using(breeze.FetchStrategy.FromLocalCache);
myEntityManager.executeQuery(q2).then(function(data) {
var myEntities = data.results;
});
The idea behind this is that with executeQuery you treat all queries in exactly the same fashion, i.e. asynchronously, regardless of whether they are actually asynchronous under the hood.
If you want to create an EntityManager that does not go to the server for metadata you can do the following:
var ds = new breeze.DataService({
serviceName: "none",
hasServerMetadata: false
});
var manager = new breeze.EntityManager({
dataService: ds
});

Resources