Please see below code:
peopleObj.forEach( item=>{
let user = item.user;
let event = item.event;
var userNode = g.addV('user');
Object.keys(user).forEach(att=>{
console.log('att: ' + att+", val: "+ user[att]);
userNode.property(att, user[att]);
});
userNode.next();
console.log('created userNode');
eventNode = g.addV('event');
Object.keys(event).forEach(att=>{
console.log('att: ' + att+", val: "+ event[att]);
eventNode.property(att, event[att]);
});
eventNode.next();
console.log('created eventNode');
// const names = await g.V().hasLabel('event').values('name').toList();
// console.log(names);
var u_p = g.V().hasLabel('user').has('name',user.name).next();
var e_p = g.V().hasLabel('event').has('name',event.name).next();
var r1 = g.V(u_p).addE('triggers').to(e_p);
r1.next();
}
when I run it in console, I see below error:
(node:30272) UnhandledPromiseRejectionWarning: Error: Server error: Could not locate method: DefaultGraphTraversal.to([{}]) (599)
at DriverRemoteConnection._handleMessage (/Users/frankhe/projects/aws/sam-app/hello-world/node_modules/gremlin/lib/driver/driver-remote-connection.js:180:9)
I followed the Gremlin V3 doc, why the node can be added, but the edge can not be added here?
Another question is in Gremlin, what is the best approach to check existence before creating? if you look at code, I am just creating event directly, but I need to avoid duplicated events, I tries to use await as indicated in the doc, but there is NO await at all in nodeJS. can anyone tell me the best approach provided by Gremlin?
Thanks in advance.
Answer:
My gremlin nodejs is:
"gremlin": "^3.3.4"
and my gremlin server is
apache-tinkerpop-gremlin-server-3.3.4
The most important problem is no matter how I did, I always meet this error:
Server error: Could not locate method: DefaultGraphTraversal.to([{}])
I changed to asyn way already, but useless. Can anyone show me a working sample for using nodeJS with Gremlin?
Thanks
The simplified version is here:
var g1 = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
var v1 = g1.addV('user').property('name','Frank').next(()=>{
console.log('created1')
var v2 = g1.addV('event').property('name','Event1').next(()=>{
console.log('created2')
g1.V(v1).addE('trigger').to(v2).property('weight',0.75).iterate();
});
});
But in the console. I never saw he log info for created1 at all.
Can you give me a working sample in nodeJS?
You are mixing sync and asynchronous executions in the same code.
Consider that when you use:
userNode.next();
console.log('created userNode');
The message is incorrect. next() returns a Promise that gets resolved asynchronously (see: RemoteConnection Submission).
The correct usage would be:
userNode.next().then(() => console.log('created userNode'));
or, if you are using async functions:
await userNode.next();
console.log('created userNode');
Just removed the .next() and g.V(v1) calls and now the example is working well:
const v1 = await g.addV('person').property('name','marko');
const v2 = await g.addV('person').property('name','stephen');
await v1.addE('knows').to(v2).property('weight',0.75).iterate();
I'm using: gremlin#3.4.1
Related
When doing normal transactions in Firebase you can just use the .add function to add a new document with an auto generated ID; however, when doing a batch write with Web version 9 of the API I cannot find any documentation on how to add a new document with a auto generated ID. Currently I have the following code which is not working:
let ref = doc(db, "projects", doc())
batch.add(ref, element);
await batch.commit();
This throws the error "Function doc() cannot be called with an empty path.". In Web version 8 this worked apparently by just calling .doc(). How does one accomplish this?
This is what worked for me:
let ref = doc(collection(db, "projects"))
For Node.js, or using the Firebase V8 syntax, a working solution would be:
let ref = db.collection("projects").doc()
batch.set(ref, {...data})
...
According to the Firebase documentation on adding a document:
In some cases, it can be useful to create a document reference with an auto-generated ID, then use the reference later. For this use case, you can call doc():
import { collection, doc, setDoc } from "firebase/firestore";
// Add a new document with a generated id
const newCityRef = doc(collection(db, "cities"));
// later...
await setDoc(newCityRef, data);
So it seems you'll need:
let ref = doc(db, collection("projects"))
I'm now implement a program to migrate large amount of data to ADX base on Ingest from Storage feature of ADX and I'm need to check that status of each ingestion request each time the request finish but I'm facing an issue
Base on MS document in here
If I set the persistDetails = true for example with the command below it must save the ingestion status but currently this setting seem not work (with or without it)
.ingest async into table MigrateTable
(
h'correct blob url link'
)
with (
jsonMappingReference = 'table_mapping',
format = 'json',
persistDetails = true
)
Above command will return an OperationId and when I using it to check export status when the ingest task finish I always get this error message :
Error An admin command cannot be executed due to an invalid state: State='Operation 'DataIngestPull' does not persist its operation results' clientRequestId: KustoWebV2;
Can someone clarify for me what is the root cause relate to this? With me it seem like a bug relate to ADX
Ingesting data directly against the Data Engine, by running .ingest commands, is usually not recommended, compared to using Queued Ingestion (motivation included in the link). Using Kusto's ingestion client library allows you to track the ingestion status.
Some tools/services already do that for you, and you can consider using them directly. e.g. LightIngest, Azure Data Factory
If you don't follow option 1, you can still look for the state/status of your command using the operation ID you get when using the async keyword, by using .show operations
You can also use the client request ID to filter the result set of .show commands to view the state/status of your command.
If you're interested in looking specifically at failures, .show ingestion failures is also available for you.
The persistDetails option you specified in your .ingest command actually has no effect - as mentioned in the docs:
Not all control commands persist their results, and those that do usually do so by default on asynchronous executions only (using the async keyword). Please search the documentation for the specific command and check if it does (see, for example data export).
============ Update sample code follow suggestion from Yoni ========
Turn out, other member in my team mess up with access right with adx, after fixing it everything work fine
I just have one concern relate to PartiallySucceeded that need clarify from #yoni or someone have better knowledge relate to that
try
{
var ingestProps = new KustoQueuedIngestionProperties(model.DatabaseName, model.IngestTableName)
{
ReportLevel = IngestionReportLevel.FailuresAndSuccesses,
ReportMethod = IngestionReportMethod.Table,
FlushImmediately = true,
JSONMappingReference = model.IngestMappingName,
AdditionalProperties = new Dictionary<string, string>
{
{"jsonMappingReference",$"{model.IngestMappingName}" },
{ "format","json"}
}
};
var sourceId = Guid.NewGuid();
var clientResult = await IngestClient.IngestFromStorageAsync(model.FileBlobUrl, ingestProps, new StorageSourceOptions
{
DeleteSourceOnSuccess = true,
SourceId = sourceId
});
var ingestionStatus = clientResult.GetIngestionStatusBySourceId(sourceId);
while (ingestionStatus.Status == Status.Pending)
{
await Task.Delay(WaitingInterval);
ingestionStatus = clientResult.GetIngestionStatusBySourceId(sourceId);
}
if (ingestionStatus.Status == Status.Succeeded)
{
return true;
}
LogUtils.TraceError(_logger, $"Error when ingest blob file events, error: {ingestionStatus.ErrorCode.FastGetDescription()}");
return false;
}
catch (Exception e)
{
return false;
}
I am simply trying to add a record to the database with a cloud function. For some reason, I am getting the above error. This doesn't make sense as I am not making any calls inside the method. At first, I thought it might have something to do with a return, but I tried every combination of return or not returning and nothing worked. Please help
Here is how I call the cloud function
function sendFriendRequest(userUid)
{
//userUid is user that will recieve request
var curUser = firebase.auth().currentUser;
userUid = userUid.substring(1);
var sendRequest = firebase.functions().httpsCallable('sendFriendRequest');
sendRequest({data: {sendingUser: curUser, recievingUser: userUid}}).then(function(result) {
//No return
});
}
Here is the cloud function
exports.sendFriendRequest = functions.https.onCall((data, context) => {
console.log("Made it to sendFriendRequest");
var requestedUserProfileRef = admin.database().ref("Users/" + data.data.recievingUser + "/FriendRequests");
requestedUserProfileRef.child(data.data.sendingUser.uid).set(data.data.sendingUser.displayName);
console.log("Finished sendFriendRequest");
});
I eventually figured this out and thought that I might as well share it with anyone who might need it in the future. So what was wrong was that I was passing in an object as the value for sendingUser. Apparently, you cant do that. Its a weird error and it doesn't seem to correspond to the actual error.
i tried to retrieve data from firebase with angular2 today without success, i can console log data and see object, but for reusing them i have undefined in the console, maybe an issue with synchronous and asynchronous data, what kind of solution i have to retrieve these data with angular2?
thank you
read(){
this.publicationUrl = "https://FBURL/publication";
this.PublicationRef = new Firebase(this.publicationUrl);
this.PublicationRef.on("child_added", function(snapshot){
this.publication = snapshot.val();
console.log(this.publication)
})
}
The issue is that you set data to the wrong this object. Use arrow function to preserve lexical scope:
read() {
this.publicationUrl = "https://FBURL/publication";
this.PublicationRef = new Firebase(this.publicationUrl);
this.PublicationRef.on("child_added", snapshot => {
this.publication = snapshot.val();
console.log(this.publication);
});
}
I have no issues when using implicit updates (angelFire). However I need for some of my data use explicit updating. So I implemented angelFireCollection on the exact same ref I was using previously but despite the console.log explicitly saying that the read was granted and trying it with both with the onloadcallback and without, I don't get data directly into my assigned variable AND once the callback fires I get a strange looking object that DOES contain the data but not in the form I expect. My scope variable ends up with an empty collection. Never gets populated. Here is the code:
var streamController = function ($rootScope, $scope, $log, $location, angularFireCollection, profileService) {
//Wait for firebaseLogin...
$rootScope.$watch('firebaseAuth', init);
function init() {
if ($rootScope.firebaseAuth == false) {
return
};
var refUsers = new Firebase($rootScope.FBURL+'/users/'+$rootScope.uid);
$scope.profile = angularFireCollection(refUsers, function onload(snapshot) {
console.log(snapshot)
});
};
};
myApp.gwWebApp.controller('StreamController', ['$rootScope', '$scope', '$log', '$location', 'angularFireCollection', 'profileService',
streamController]);
}());
Here is what the console.log looks like ( ie; what snapshot looks like ):
>snapshot
T {z: R, bc: J, V: function, val: function, xd: function…}
Here is the earlier message before the snapshot was returned:
Firebase Login Succeeded! fbLoginController.js:16
FIREBASE: Attempt to read /users/529ccc5d1946a93656320b0a with auth={"username":"xxxxxxx#me.com","id":"529ccc5d1946a93656320b0a"} firebase.js:76
FIREBASE: /: "auth.username == 'admin'" firebase.js:76
FIREBASE: => false firebase.js:76
FIREBASE: /users firebase.js:76
FIREBASE: /users/529ccc5d1946a93656320b0a: "auth.id == $user" firebase.js:76
FIREBASE: => true firebase.js:76
FIREBASE:
FIREBASE: Read was allowed.
and finally the desired binding that ends up with an empty array: again from the console:
$scope.profile
[]
Anyone know what I could possibly be doing wrong?? This is like 5 lines of code. Frustrating.
I have put stops in angelFireCollection factory function and can see that the data is getting added to the collection in the callbacks inside that function but my binded variable never gets updated.
UPDATE
Ok experimenting with a plnkr. It seems that angularFireCollection EXPECTS your returning a LIST of items. The snapshot returns properly if you inspect snapshot.val() it will be whatever object structure was stored in firebase. IF you use angularFireCollection it does indeed bind to the variable HOWEVER it turns a non-list object into a garbled mess and you can not access the object user the normal dot operator. This is either a bug or it is a severe limitation of angularFireCollection which will cause me to revaluate how easily I can use firebase as the backend. I can't share my plnkr because it is accessing non-public data but tomorrow if i have time I will create a public firebase with an object store and demonstrate.
Ok. So it appears that indeed angularFireCollection is MEANT to be array based. Which is fine. It would be VERY helpful if the angularFire documentation was updated to make that clear. As such it is not an implicit vs explicit update technique.
For an explicit non-array based approach I have come up with the following code. Had I not been mislead by the documentation I would have gone down this path originally.
var MainCtrl = function($scope, angularFire) {
$scope.test = {};
var _url = 'https://golfwire.firebaseio.com/tmp';
var _ref = new Firebase(_url);
var promise = angularFire(_ref, $scope, 'implicit');
promise.then ( function(data){
$scope.explicit=angular.copy($scope.implicit );
});
}
You then work locally with the 'explicit' copy and when ready just update the 'implicit' by assigning: $scope.implicit = $scope.explicit.
Here is a plnkr: http://plnkr.co/edit/bLJrL1