Using Predicate in gremlin javascript - node.js

I want to use gremlin-javascript to traverse the remote graph and get a list of vertex, whose id is within a list of predefined ids.
const gremlin = require('gremlin');
const Graph = gremlin.structure.Graph;
const GraphPredicate = gremlin.process.P;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const graph = new Graph();
const g = graph.traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
g.V()
.has('id', GraphPredicate.within([414, 99999]))
.toList()
.then(function (result) {
console.log(result);
});
Above are the codes I have tried, but it gave me an empty list of vertex, whereas, I expected to have a vertex(414) in the result.
Moreover, when I tested with the gremlin-console by using the statement below, it gave me the vertex(414) in the result.
:> g.V().hasId(within(414,99999))
So I have some questions here:
Do I miss something in the configuration in order to use Predicate?
In the method of javascript GraphPredicate.within([414, 99999])) is the parameter supposed to be only an array of elements or a list of elements separated by a comma as in the case with gremlin-console? By the way, I have tried both ways, but I always got an empty result.
Thank you in advance,

The id is an special property in TinkerPop and can't be retrieved using the name property "id".
The correct way to retrieve by ids in your case should be:
g.V().hasId(P.within(414, 99999)).toList()
.then(result => console.log(result));
Additionally, this can be simplified by removing the within() call:
g.V().hasId(414, 99999).toList()
.then(result => console.log(result));

I can't comment, but in order to use id, you need to use gremlin.process.t.id
Example:
in Gremlin .by(id)
in JS .by(gremlin.process.t.id)
Hope this is helpful

Related

How do I use Jest to test that one text element comes before another?

I have a list I'm rendering in my React app, and I need to test that I'm listing the list items in alphabetical order.
Initially I tried testing this by querying the document this way:
const a = getByText("a_item");
const el = a.parentElement?.parentElement?.nextSibling?.firstChild?.textContent;
expect(el).toEqual("b_item");
But this proved to be brittle. I don't want to test the HTML structure of each item. I only want to test that the list is alphabetical.
How can I test that the list is alphabetical without depending on the current HTML structure of the list?
Use String.search to find the indices of the strings in the document's HTML, and then assert that indices are in the correct order:
it("lists items alphabetically", async () => {
loadItems([
"b_item",
"a_item",
]);
await render(<App/>);
await waitFor(() => {
const html = document.body.innerHTML;
const a = html.search("a_item");
const b = html.search("b_item");
expect(a).toBeLessThan(b);
});
});
Note that this may not be ideal since it accesses the dom directly, which isn't considered best practice when using React Testing Library. I haven't tested this, but it would probably be better to use a regex matcher with a built-in React Testing Library query method:
it("lists items alphabetically", async () => {
loadItems([
"b_item",
"a_item",
]);
await render(<App/>);
expect(await screen.findByText(/a_item.+b_item/)).toBeInTheDocument();
});

Tabulator: How to get the set of column (fields) that are currently grouped?

In tabulator we have:
table.setGroupBy("gender"); or table.setGroupBy(["gender","age"]);
I'm looking for a way to query the table and find out what that current list of groupBy is. I can't find any prototype function that seems to do this. Something like table.getGroupBy() ?
I did try iterating over columns, but can't find a function or property that will tell me this. Any idea how to accomplish this?
You should use the getGroups function:
var groups = table.getGroups();
This will return an array of Group Components, each one representing one of the top level groups of the table.
You can then iterate over these and get the fields and keys for each group using the getField and getKey functions on the component:
var groups = table.getGroups();
groups.forEach((group) => {
var key = group.getKey();
var field = group.getField();
});
If you are working in a table with nested groups then you can call the getSubGroups function on each component to get an array of the child group components for that group:
var groups = table.getGroups();
groups.forEach((group) => {
var key = group.getKey();
var field = group.getField();
var children = group.getSubGroups();
});
You could then recurse through these until you have all of the data you need.
Finally found it, not documented but hopefully it can be trusted:
table.options.groupBy

Node map can be called by key, but not forEach()

I have the below code that allows me to log a specific Map() key to the console, but cannot produce any output using a for each:
let teamlist = new Map()
//code to populate the map
console.log(teamlist) //Shows entire map and data in console
console.log(teamlist[0]) //Shows one entry from the map
teamlist.forEach(team =>{
console.log(team) //Shows no console output, not even "undefined"
})
I assumed this was going to be an issue due to async, but doesn't make sense as I can call individual keys? Can I not call a forEach() on a map?
Your situation could happen if you didn't add items to the Map properly.
For example, if you did this:
let teamlist = new Map();
teamlist[0] = "hello";
Then, what you did there was add a [0] property to the teamlist object and did not add an entry to the Map itself. Remember, every Map object is also a regular Object and can have regular properties that are not part of the Map specific data structure. To add an item to a Map object, you must use the .set() method like this:
let teamlist = new Map();
teamlist.set("some greeting", "hello");
teamlist.set("another greeting", "goodbye");
teamlist.forEach(team => {
console.log(team);
});
Of course, if you show us the code you're using to actually add items to the Map object, then we can answer more specifically with specific corrections to that code.
Can I not call a forEach() on a map?
You can, but it only iterates items that are actually in the Map data structure.
I assumed this was going to be an issue due to async
You don't show us any asynchronous code at all. If you do have asynchronous code, then we can only comment on its correct use if you show us that actual code.

Set property in gremlin-node.js/gremlin-server not working

I want to create a graph within gremlin-server from a node.js backend with the javascript driver of gremlin. As I added two properties, one id and one username, the id is working, the username is not stored. Here is the code:
const gremlin = require('gremlin');
const traversal = gremlin.process.AnonymousTraversalSource.traversal;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const g = traversal().withRemote(new DriverRemoteConnection('ws://localhost:8182/gremlin'));
const { t: { id } } = gremlin.process;
const { cardinality: { single} } = gremlin.process;
async function createUser(userid,username) {
const vertex = await
g.addV('User')
.property(id,userid)
.property(single,'username',username)
.iterate();
return vertex;
}
await createUser(1001,"testuser")
The output is (when I search the node with g.V(1001).listAll();) The properties are always undefined.
[Vertex { id: 1001, label: 'User', properties: undefined }]
The gremlin server was loaded/run with docker with the following commands:
docker pull tinkerpop/gremlin-server
docker run -d -p 8182:8182 --name gremlin tinkerpop/gremlin-server
The gremlin-driver in node.js has a the version: "gremlin": "^3.4.10",
I've tried with and without the cardinality single above, added more properties, but non is working. The internet searches showed some gremlin-console(groovy) working examples with the .property step, but no hint for the combination node.js-driver of gremlin and the gremlin-server.
I imagine your code is working fine and that the properties are present. The issue is that graph elements returned from queries are "references" only - meaning, they only include id and label and no properties. You should convert your results to use generic containers like Map using a step like elementMap(). You can find more discussion on this in the documentation in various places, but perhaps start with this and if you are interested more in why this is the way it is and what challenges are involved in changing it, please see this.

How to get full index information using NodeJS MongoDB to be able to recreate the same index

Docs say, use Collection.indexInformation({full: true}) to return full information about the indexes on collection. However, this only gives partial info.
https://mongodb.github.io/node-mongodb-native/3.5/api/Collection.html#indexInformation
I need full info so that I can "copy" (recreate) the same index on a different collection.
What am I doing wrong? Thanks!
The response does not separate the options and keys of index, rather it merges them into one object. To be able to recreate the same index, you need to parse it.
export function parseIndexInformation(index) {
const keys = index.key;
const options = {};
delete index.v;
delete index.ns;
delete index.key;
for (let option in index) {
options[option] = index[option];
}
return {keys, options};
}

Resources