How to specify properties to ignore in valueMap with Gremlin? - gremlin

My customer vertex has 4 properties. If I need a map representation of those properties I can get them by executing
g.V('customerId').valueMap('firstName', 'middleName', 'lastName', 'age')
But, if I need all properties excluding age in my map, is there a way to specify just the list of ignored properties? Something like
g.V('customerId').valueMap(not('age'))
I want to avoid specifying all the required properties.

There is no built-in step for it.
You can achieve this goal by unfolding each map, filter the unwanted properties (keys), and regroup it again:
g.V().valueMap().local(unfold()
.where(select(keys).is(without(["age","prop1","prop2"])))
.group().by(select(keys)).by(select(values)))

The answer Kfir provided is good. Another way is a bit more direct in my mind because you don't have the expense of first creating a Map, deconstructing it to filter, and then putting it back together:
gremlin> g.V().map(properties().hasKey(without('age')).group().by(key()).by(value()))
==>[name:marko]
==>[name:vadas]
==>[name:lop,lang:java]
==>[name:josh]
==>[name:ripple,lang:java]
==>[name:peter]
This approach just explodes vertices to properties, filters the key you don't want and then constructs a Map from that.

Related

Riak: searchable list of maps (with CRDTs)

I have a use-case which consist in storing several maps under an attribute. It's the equivalent JSON list:
[
{"tel": "+33123456789", "type": "work"},
{"tel": "+33600000000", "type": "mobile"},
{"tel": "+79001234567", "type": "mobile"}
]
Also, I'd like to have it searchable at the object level. For instance:
- search entries that have a mobile number
- search entries that have a mobile number and whose number starts with the string "+7"
Since Riak doesn't support sets of maps (but only sets of registers), I was wondering if there is a trick to achieve it. So far I've had 2 ideas
Map of maps
The idea is to generate (randomly?) keys for the objects, and store each object of the list in a parent map whose keys are the ones generated for this only purpose to have a key.
It seems to me that it doesn't allow to search the object (maps inside the parent map) because Riak Solr search requires the full path to the attribute. One cannot simply write the following Solr query: phone_numbers.*.tel:+7*. Also composed search (eg. search entries that have a mobile number and whose number starts with the string "+7") seem hard to achieve.
Sets with simulated multi-valued attributes
This solution consists in using a set and insert all the values of the object as a single string, with separators between them. Yes, it's a hack. An attribute value would look like: $tel:+79001234567$type:mobile$ with : as the attribute name-value separator and $ as the attribute separator.
Search could be feasible using the * wildcard (ugly, but still), except the problem with escaping the separators: what if the type attribute includes a :? Are they some separators that are accepted by Riak and would not be acceptable in a string (I'm thinking of control characters)?
In a nutshell
I'm looking for a solution whatever the hackiness of it, as long as it works. Any idea is welcome.

Can we filter multiple labels simultaneously

I have a scenario where I have to check multiple vertices with different labels and match their properties under a parent vertex. And then return the parent vertex if everything matches fine.
I tried writing queries with 'and' clause and 'where' clause but none is working:
Here are my trials:
g.V().hasLabel('schedule').inE().outV().hasLabel('url').as('a').outE().inV().aggregate('x').hasLabel('schedule').has('name', '3').as('b').select('x').hasLabel('states').has('name', 'federal').as('c').select('a')
g.V().hasLabel('schedule').inE().outV().hasLabel('url').as('a').outE().where(inV().hasLabel('schedule').has('name', '3')).where(inV().hasLabel('states').has('name', 'federal')).select('a')
g.V().hasLabel('schedule').inE().outV().hasLabel('url').as('a').outE().and(inV().hasLabel('schedule').has('name', '3'),inV().hasLabel('states').has('name', 'federal')).select('a')
g.V().hasLabel('schedule').inE().outV().hasLabel('url').as('a').outE().inV().aggregate('x').hasLabel('schedule').has('name', '3').as('b').select('x').unfold().hasLabel('states').has('name', 'federal').as('c').select('a')
Please guide me through the right path
You can definitely simplify your approach. I don't think you need the step labels and select() for what you are doing which is good, because they add cost to your traversal. I tried to re-write the first traversal you supplied and I"m hoping I have the logic right, but regardless, I'm thinking you will get the idea for what you need to do when you see the change:
g.V().hasLabel('schedule').in().hasLabel('url').
where(and(out().hasLabel('schedule').has('name', '3'),
out().hasLabel('states').has('name', 'federal')))
You already have the "parent" that you want to return on the first line, so just do a filter with where() and add your filtering logic there to traverse away from each of those "parents".

How to retrieve more than 2 properties in a path in gremlin.

I wanted to get two properties as results but i got only one. what i did was using the given code in gremlin
g.V().repeat(out()).until(has('title','school')).path().by('title').by('name')
how to get with both of them.
The by() modulators are applied round-robin to the Path objects so, for the first item in the path you'll get "title", then the second item will get "name", then the third item, 'title'. If you want both "title" and "name" for each vertex in the path then you need to specify that in a single by().
by() can take more than just a string (i.e. property key) as a value. It can also take a traversal and therefore you have many options to get what you want. Here's one way to do it:
g.V().repeat(out()).until(has('title','school')).
path().by(values('name','title').fold())

Defining OpenFOAM fields as functions of space

I have some initial conditions that are specified by functions of (x,y,z).
I would like to programmatically define a field whose values are a function of (x,y,z). Can this be done as part of field construction, rather than looping over cells/faces and setting each value individually?
Further, can I set the internal field and boundary values in a straightforward manner?
You might want to use #codeStream directive to enter the generating code directly in the field defining dictionary, see official documentation.
Also you might want to look at extensions such as groovyBC, funkySetFields or swak4Foam.

How to store and retrieve different types of Vertices with the Tinkerpop/Blueprints graph API?

When looking at the Tinkerpop-Blueprints API it is quite straight forward to use one type of vertices but how can I store two? E.g. Users and their interests?
And how can I get a Vertex by id? I mean, there could be a user named 'timetabling' as well as the interests 'timetabling' - how to handle that id conflict?
-
I know that the first problem could be solved via introducing an index for a type-property and for the second problem I could auto generate the id and create another index for the name-property. BUT why would I then need the vertex id at all? E.g. for the in-memory there is a HashMap for all vertices which would be of no use and wasting memory! (I could solve the problem differently via combining type and name as the id but then it would inefficient if I e.g. list all users.)
Hmmh, ok. I'm just using the vertices for the combined id (name+type) and a separate index for type. Better solutions?
In general it is best to rely on the automatic ID system of the underlying graph database (e.g. Neo4j, InfiniteGraph, OrientDB, etc.). The way in which you would add the information you want is as follows:
Vertex v = graph.addVertex(null)
v.setProperty("name","timetabling")
Vertex marko = graph.addVertex(null)
graph.addEdge(null, marko, v, "hasInterest")
Verte aType = graph.addVertex(null)
graph.addEdge(null, aType, v, "hasType")
In short, the ID of a vertex/edge is a non-domain-specific way of retrieving vertices/edges. Generally, it is best to use properties in your domain model for indexing.
Hope that speaks to your question,
Marko.
http://markorodriguez.com

Resources