currently have a cypher query method
public static void RunQuery(String _query)
{
Properties prop = new Properties();
final String DB_PATH = "path/to/db"
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
ExecutionEngine engine = new ExecutionEngine(graphDb);
ExecutionResult result = engine.execute(_query);
for(Map<String,Object> map : result)
{
System.out.println(map.toString());
}
graphDb.shutdown();
}
However this only allows me to get results like this:
{a=Node[11303]}
{a=Node[11341]}
{a=Node[11343]}
{a=Node[11347]}
{a=Node[11349]}
{a=Node[11378]}
How can I augment it to spit out the entire query results like the cypher shell does?
What does your query look like. The Map<String, Object> that is returned will have a key of the variable you return. The Object can be a Path, Node, or Relationship, and this will just call the native toString() on them, which in Java code just returns the Node ID. You have to build your own printer, something that will get the property keys and iterate through each of them.
for (String key : node.getPropertyKeys()) {
System.out.println("Key: " + key + ", Value: " + node.getProperty(key));
}
It depends on the RETURN of your query..
For example, if you have a query like this:
_query="Start x= node(someIndex) Match x-[rel:SOMETHING]-n Return n";
So, your code can be
ExecutionResult result = engine.execute(_query);
Iterator<Node> n_column = result.columnAs("n");
for (Node outputNode: IteratorUtil.asIterable(n_column)) {
System.out.println(outputNode.getProperty("yourKey","defaultValueIfNull"));
}
Related
The idea behind parametrized queries is to re-use (cache) execution plans.
If a node label or a relationship type do not vary, the execution plan would be the same at all, thus benefits can be achieved of execution plan caching.
Currently, I'm my complete Cypher Query is built using Java String Building. Instead of creating the entire Cypher Query using String building I want to pass the values of the Properties as Parameter Values along with Property Names as Parameters or not. I need sample code, guidance for the same.
My Current Code
import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Session;
public class ForStackoverflowQuestion {
public static void main(String[] args) {
Driver driver = GraphDatabase.driver(
"bolt://localhost:7687", AuthTokens.basic("neo4j", "12345"));
Session session = driver.session();
String Node1 = "Software_Engineer";
String Node2 = "Programming_Language";
String relationBetweenNode1andNode2 = "LEARNS";
String PersonNameAttribute = "name";
String PersonNameValue = "Jaykant";
String ProgrammingLanguageAttribute = "version";
String ProgrammingLanguageValue = "Neo4j";
String t = "MERGE(n1:"+Node1+"{"+PersonNameAttribute+":\""+PersonNameValue+"\"})"+"-[:"+relationBetweenNode1andNode2+"]->(n2:" + Node2 +" {"+ProgrammingLanguageAttribute+":'"+ProgrammingLanguageValue+"'})";
System.out.println(t);
session.run(t);
session.close();
driver.close();
}
}
I understand that my above code is not using Parameterized Cypher Query; so it will not generate any Query Plan in neo4j.
In order to use and benefit from the Query Plan, I need to use the Parametrized Query.
If not Node1, Node2, and relationBetweenNode1andNode2 as Parameters then at least following values can be passed as parameters.
PersonNameAttribute = "name";
PersonNameValue = "Jaykant";
ProgrammingLanguageAttribute = "version";
ProgrammingLanguageValue = "Neo4j";
Any sample code? Tutorial?
You can pass parameters along with query in session.run() method.
Ex.
session.run(query, parameters)
Parameters should be a Map.
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("PersonNameValue", "Jaykant");
parameters.put("ProgrammingLanguageValue", "Neo4j");
Query can be modified as:
String t = "MERGE (n1:"+Node1+"{"+PersonNameAttribute+":{PersonNameValue}})"+"-[:"+relationBetweenNode1andNode2+"]->(n2:" + Node2 +" {"+ProgrammingLanguageAttribute+": {ProgrammingLanguageValue}})";
Finally run statement:
session.run(t, parameters);
So, I read my MongoDB this way:
mongo = new MongoClient("localhost", 27017);
// Accessing the database
MongoDatabase database = mongo.getDatabase("myDb");
MongoCollection<Document> collection = database.getCollection("searchresults");
// Getting the iterable object
FindIterable<Document> iterDoc = collection.find();
int i = 1;
// Getting the iterator
Iterator it = iterDoc.iterator();
while (it.hasNext()) {
System.out.println(it.next());
i++;
}
}
As you can see, each line has several columns: Title, etc. So, when I iterate over myDB, i want to parse each line by its value instead of get all in one line.
Any suggestions?
You can try reading into a Document structure, then run another loop across each of the entries. This will give each value on its own line.
FindIterable<Document> iterDoc = database.getCollection("").find();
for(Document doc : iterDoc) {
for(Map.Entry<String, Object> entry : doc.entrySet()) {
System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
}
}
If you only want certain keys, use a projection in your find query
This is not a fitting answer to your question, but i would look in to a concept thats called Object-Document-Mapping (ODM). It simplifies some boilerplate code that you have to care about. A common library for MongoDB-ODM is called Morphia :)
The ask: a function to retrieve a single Entity from the Google App Engine Datastore based on a property that is not its Key or otherwise return null if no such object is found.
Here is the function I have currently:
public Entity find(DatastoreService datastore, String kind, String property, String value) {
Filter propertyFilter =
new FilterPredicate(property, FilterOperator.EQUAL, value);
Query q = new Query(kind).setFilter(propertyFilter);
List<Entity> results =
datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
if (results.isEmpty()) {
return null;
}
return results.get(0);
}
Is there a one-shot API I could use instead or are there any optimization suggestions?
You could use PreparedQuery#asSingleEntity():
public Entity find(DatastoreService datastore,
String kind, String property, String value)
throws TooManyResultsException {
Filter propertyFilter =
new FilterPredicate(property, FilterOperator.EQUAL, value);
Query q = new Query(kind).setFilter(propertyFilter);
return datastore.prepare(q).asSingleEntity();
}
The only real difference between this and your code is that the underlying query sets a LIMIT of 2.
I am trying to do fetch the data from database using ScrollableResults. Part of my code is below :
List list = null;
ScrollableResults items = null;
String sql = " from " + topBO.getClass().getName(); // topBO is my parent class so i pass the any of my child class name .
StringBuffer sqlQuery = new StringBuffer(sql);
Query query = sessionFactory.getCurrentSession().createQuery(sqlQuery.toString());
items = query.scroll();
int i = 0;
TopBO topBO;
while(items.next())
{
topBO= (TopBO) items.get()[i];
list.add(TopBO2); // got the exception at this line.
i++;
topBO= null;
}
items.close();
If i run the above code i am getting runtime error like java.lang.NullPointerException
You are trying to add the value in list which is not initialize.
It may helps you :
List list = new ArrayList();
replace with
List list = null;
I think topBO= (TopBO) items.get()[i]; is causing the problem.
I would suggest that you use result set transformer of query something like this
Query query = sessionFactory.getCurrentSession().createQuery(sqlQuery.toString());
list=query.setResultTransformer(Transformers.aliasToBean(YourClassName.class)).list();
I would like to be able to use the mongodb group command with the 'keyf' parameter through the java driver. Has anyone been successful with this?
You have to use the deprecated method DBCollection.group(DBObject args) and add the key function javascript code as a string under the DBObject key named "$keyf".
BasicDBObject args = new BasicDBObject();
args.put("ns", nameSpace);
args.put( "initial" , initialDBObject );
args.put( "cond" , queryDBObject );
args.put( "$reduce" , reduceJavasriptCodeString );
args.put("$keyf", keyfJavascriptCodeString );
if( finalize != null ) args.put("finalize", finalizeJavascriptCodeString );
DBObject groupResult = mydbCollection.group(args);
This piece of code should do the work for you:
public static CommandResult exeMapReduceAlikeGroupCmd(DB db, String colName, String keyFunc, DBObject query,
String reduceFunc, DBObject initial) {
BasicDBObject cmd = new BasicDBObject("ns", colName);// this is the collection name
cmd.append("$keyf", keyFunc);// keyf function
cmd.append("cond", query); // cond query object
cmd.append("$reduce", reduceFunc);// reduce function
cmd.append("initial", initial);// initial value
cmd = new BasicDBObject("group", cmd);
return db.command(cmd, db.getOptions());
}