Use Gremlin with Java API for OrientDB - traversal

I'm using Gremlin to traverse OrientDB, but I'm not quite understand the demo code from here OrientDB Gremlin Wiki
Here is my code, what's wrong with this code?
// create sample node and edge
graph = new OrientGraph("local:C:/temp/graph/db");
Vertex v1 = graph.addVertex(null);
v1.setProperty("name", "A");
Vertex v2 = graph.addVertex(null);
v2.setProperty("name", "B");
Vertex v3 = graph.addVertex(null);
v3.setProperty("name", "C");
graph.addEdge(null, v1, v2, "KNOWS");
graph.addEdge(null, v1, v3, "KNOWS");
OGremlinHelper.global().create();
OCommandGremlin command = new OCommandGremlin("g.v('#8:0').out('KNOWS').aggregate(x).has('name',name)");
Map<String, Object> params = new HashMap<String, Object>();
List agg = new ArrayList();
params.put("x", agg);
params.put("name", "B");
Vertex vertex = graph.getRawGraph().command(command).execute(params);
System.out.println(vertex);
System.out.println(agg);
I can get the final result of the script, but why can't I get the "aggregate" result? How can I get it?
I'm really new to it. Thanks in advance!

https://github.com/nuvolabase/orientdb/wiki/Gremlin Here said that output can only be declared with parameters passed to ScriptEngine, and the output must be an HashMap. Hope OrientDB team will enhance this at the next version.

Related

Lucene .net + equivalent of SpanMultiTermQueryWrapper<MultiTermQuery> in C#

I need to convert the following Java code to C# but I couldn't find the equivalent of "SpanMultiTermQueryWrapper". Could you please help?
FuzzyQuery firstNameQuery = new FuzzyQuery(new Term("text", firstName), 2);
FuzzyQuery lastNameQuery = new FuzzyQuery(new Term("text", lastName), 2);
SpanQuery[] clauses = new SpanQuery[] {
new SpanMultiTermQueryWrapper<MultiTermQuery>(firstNameQuery),
new SpanMultiTermQueryWrapper<MultiTermQuery>(lastNameQuery)
};
SpanNearQuery spanNearQuery = new SpanNearQuery(clauses, 3, false);
SpanMultiTermQueryWrapper and MultiTermQuery are both available on Lucene.Net 4.8.0-beta00004.
If you need support in earlier versions of Lucene.Net, you can probably just grab the source code from the above links and any dependencies and drop them into a library for your applications.

Retrieving single property value in Gremlin query closure works, but retrieving valueMap() fails yields Exception

Using the Titan 1.0.0 Gremlin shell I can retrieve a single property value from an edge from within a closure. But trying to access the valueMap() fails with an exception.
Works:
gremlin> t.E().hasLabel("TRUSTS").has('NOT_VALID_BEFORE').each( { trustEdge -> t.E().has('EDGE_GROUP_ID', trustEdge.value('EDGE_GROUP_ID')).hasNot('NOT_VALID_BEFORE').each({println it.value('EDGE_ID')}) } )
Yields exception (only difference is in the right most closure 'it.valueMap()' vs 'it.value('..')'):
gremlin> t.E().hasLabel("TRUSTS").has('NOT_VALID_BEFORE').each( { trustEdge -> t.E().has('EDGE_GROUP_ID', trustEdge.value('EDGE_GROUP_ID')).hasNot('NOT_VALID_BEFORE').each( { println it.valueMap() } ) } )
No signature of method: com.thinkaurelius.titan.graphdb.relations.StandardEdge.valueMap() is applicable for argument types: () values: []
Possible solutions: value(java.lang.String)
Display stack trace? [yN]
gremlin>
But it is not that in general I would be unable to get to the valueMap of the edge:
gremlin> t.E().hasLabel("TRUSTS").has('NOT_VALID_BEFORE').each( { trustEdge -> t.E().has('EDGE_GROUP_ID', trustEdge.value('EDGE_GROUP_ID')).hasNot('NOT_VALID_BEFORE').each( { println it } ) } )
e[215rmh-oe094-1d05-9i0][40964296-MANAGED->12312]
gremlin> t.E('215rmh-oe094-1d05-9i0').valueMap()
==>[MANAGE_INFORM:false, NOT_VALID_AFTER:1669873006000, MANAGE_MANAGERS:false, MANAGE_AUTHENTICATION_MEANS:true, CREATED_AT:1487683094863, RELATIONSHIP_ROLE:FAMILY_DOCTOR, MANAGE_TRUST:true, UPDATED_AT:1487683094915, MANAGE_REPRESENTATION:false, EDGE_ID:122881049, VERIFIED:true, EDGE_GROUP_ID:122881049]
Is this a bug or am I doing something wrong here?
A little context, just in case the query does not even do what I think it does:
What I think I am doing here is looking up all edges with label "TRUSTS" that have a property NOT_VALID_BEFORE. For each of those edges I look up all edges that share the same edge group ID value and check if they also have a property NOT_VALID_BEFORE, printing those to the console that do not have the property set.
When you start iterating with each(), every item you manipulate inside the closure is "off the traversal" -- that is, you're working with an Edge object, not an GraphTraversal object.
Edge has a value() method similar to the GraphTraversal, but it does not have a valueMap() method. You could use ElementHelper.propertyValueMap() instead.
Here's a quick example:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.E().valueMap()
==>[weight:0.5]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:0.2]
gremlin> g.E().each{ edge -> println ElementHelper.propertyValueMap(edge) };[]
[weight:0.5]
[weight:1.0]
[weight:0.4]
[weight:1.0]
[weight:0.4]
[weight:0.2]

mapReduce inline results with java mongodb driver 3.2

How to have inline results from a mapReducet with the mongodb java driver 3.2?
with driver version 2.x I was doing:
DBColleciont coll = client.getDB(dbName).getCollection(collName);
coll.mapReduce(map, reduce, null, OutputType.INLINE, query);
the new 3.x driver has two mapReduce() methods returning MapReduceIterable which misses a method to specify the INLINE output mode.
MongoCollection<Documetn> coll = client.getDatabase(dbName).getCollection(collName)
coll
.mapReduce(map, reduce).
.filter(query);
You can create the map-reduce command manually:
String mapFunction = ...
String reduceFunction = ...
BsonDocument command = new BsonDocument();
BsonJavaScript map = new BsonJavaScript(mapFunction);
BsonJavaScript red = new BsonJavaScript(reduceFunction);
BsonDocument query = new BsonDocument("someidentifier", new BsonString("somevalue"));
command.append("mapreduce", new BsonString("mySourceCollection"));
command.append("query", query);
command.append("map", map);
command.append("reduce", red);
command.append("out", new BsonDocument("inline", new BsonBoolean(true)));
Document result = mongoClient.getDatabase(database).runCommand(command);
I think this is extremely ugly, but it is the only working solution I found so far using 3.2. (... and would be very interested in a better variant, too... ;-))
I think I found it...
I had a deeper look into mongodb's Java driver source and it seems that the INLINE output feature is implicitly accessible:
The class MapReduceIterableImpl<TDocument, TResult>(MapReduceIterableImpl.java), which is the default implementation of the Interface return type of mapReduce(),
holds a private boolean inline with initial value true.
The only place where this can ever be switched to false is the method collectionName(final String collectionName) for which the description is as follows:
Sets the collectionName for the output of the MapReduce
The default action is replace the collection if it exists, to change this use action(com.mongodb.client.model.MapReduceAction).
If you never call this method on the object instance after mapReduce(), it will remain true as initialized...meaning: if there is no output collection, it must be inline.
Later on, when you access your result with iterator(), first(), forEach(...) etc internally the execute() method gets called which hast the magic if condition:
if (inline) {
MapReduceWithInlineResultsOperation<TResult> operation =
new MapReduceWithInlineResultsOperation<TResult>(namespace,
new BsonJavaScript(mapFunction),
new BsonJavaScript(reduceFunction),
codecRegistry.get(resultClass))
.filter(toBsonDocument(filter))
.limit(limit)
.maxTime(maxTimeMS, MILLISECONDS)
.jsMode(jsMode)
.scope(toBsonDocument(scope))
.sort(toBsonDocument(sort))
.verbose(verbose)
.readConcern(readConcern);
....
} else {
MapReduceToCollectionOperation operation =
new MapReduceToCollectionOperation(namespace, new BsonJavaScript(mapFunction), new BsonJavaScript(reduceFunction),
collectionName)
.filter(toBsonDocument(filter))
.limit(limit)
.maxTime(maxTimeMS, MILLISECONDS)
.jsMode(jsMode)
.scope(toBsonDocument(scope))
.sort(toBsonDocument(sort))
.verbose(verbose)
.action(action.getValue())
.nonAtomic(nonAtomic)
.sharded(sharded)
.databaseName(databaseName)
.bypassDocumentValidation(bypassDocumentValidation);
...so it is instanciating MapReduceWithInlineResultsOperation when collectionName() has not been called.
I had no chance to test it because my NetBeans hates me at the moment, but I think it is pretty clear.
What do you think, did I miss something?
Would be glad if I could help you shift the code to API 3.x, great project!

Mahout clustered points

When I run kmeans clustering in Mahoot I get two folders, clusters-x and clusteredPoints.
I have read cluster centers using cluster dumper, but I somehow can't get to clusteredPoints? Concretely, I need to do it from code.
The strange thing is that I file size in clusteredPoints is always 128 bytes, and when I try to loop through results, using next code, it just goes out of the loop, like there is no result, but I get the cluster centers, which leads to assumption that points are clustered.
IntWritable key = new IntWritable();
WeightedPropertyVectorWritable value = new WeightedPropertyVectorWritable();
while (reader.next(key, value)) {
System.out.println(
value.toString() + " belongs to cluster " + key.toString());
}
It just goes out of the loop?
It is really strange, any help would be great, thanks.
You need to open up your final cluster file ('clusteredPoints/part-m-0') with:
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
SequenceFile.Reader reader = new SequenceFile.Reader(fs, new Path("output/clusteredPoints/part-m-0"), conf);
then, assuming your keys are int's, iterate through it (as you already did), with:
IntWritable key = new IntWritable();
WeightedPropertyVectorWritable value = new WeightedPropertyVectorWritable();
while (reader.next(key, value)) {
LOG.info("{} belongs to cluster {}", value.toString(), key.toString());
}
reader.close();
I can post a fully working example if you still have trouble doing this.

How to update a DataSource field values?

I need to update a DataSourceTextField. Basically I do this in my code:
DataSourceTextField partDataSourceField = new DataSourceTextField(
partFieldName, constants.partTitle());
partDataSourceField.setValueMap(partCodesList);
documentsResultDataSource.setFields(partDataSourceField,
titleDataSourceField);
That code, generates a "part" list on the DataSource for me to filter the results.
What I've been trying is this dynamically change this list to set it to show only the values that are available on the results. I've tried this with no avail:
DataSourceField partField = documentsResultDataSource.getField(partFieldName);
LinkedHashMap<String, String> partCurrentCodesList = new LinkedHashMap<String, String>();
partCurrentCodesList.put("Test", "Test");
partField.setValueMap(partCurrentCodesList);
Is it possible to accomplish what I need?
I deleted the DataSourceTextField and then :
documentsResultDataSource.setFields(partDataSourceField,
titleDataSourceField);
This is sub-optimal but the best solution I found.