Rexster extension using Neo4j Lucene index - neo4j

I'm trying to write a Rexster extension in Java that among other things queries nodes using Neo4j 2.0 Lucene indices.
From the few threads I was able to find (mostly old Google Group threads), it doesn't seem to be possible using Blueprint's Graph.
I thought about a possible solution where I access the underlying Neo4jGraph class from the extension's:
#RexsterContext Graph graph
parameter, but I'm not sure how to do this.
The end-goal ideally, would be to use an automatic get-or-create-index method which could be called with a piece of text on a Lucene index.
Any ideas ?
Thank you in advance!

I think you said the answer here:
I thought about a possible solution where I access the underlying
Neo4jGraph class from the extension's:
#RexsterContext Graph graph
If you need methods from Blueprints Neo4jGraph then just cast Graph to that:
Neo4jGraph neo4j = (Neo4jGraph) neo4j;
Furthermore, if you need to work with specific, native Neo4j classes/methods then just do:
GraphDatabaseService graphdb = neo4j.getRawGraph()
Obviously both of these approaches makes your Rexster Extension Neo4j specific but it sounds like that is ok for your case.

Related

How to create a dynamic cypher query in SDN 5.x similiar to Neo4jOperations in 4.x

I am trying to implement a solution using SDN which was aimed to create a dynamic cypher where my label vary w.r.t input type(n types) irrespective of properties of Node.
Hoping a solultion similiar to what mentioned on this link would help me.
Is it possible to dynamically construct a neo4j cypher query using the GraphRepository pattern
I found the below information in Release notes.
Deprecation of Neo4jTemplate
It is highly recommended for users starting new SDN projects to use the OGM Session directly. Neo4jTemplate has been kept to give upgrading users a better experience.
The Neo4jTemplate has been slimmed-down significantly for SDN 4. It contains the exact same methods as Session. In fact Neo4jTemplate is just a very thin wrapper with an ability to support SDN Exception Translation. Many of the operations are no longer needed or can be expressed with a straightforward Cypher query.
If you do use Neo4jTemplate, then you should code against its Neo4jOperations interface instead of the template class.
The following table shows the Neo4jTemplate functions that have been retained for version 4 of Spring Data Neo4j. In some cases the method names have changed but the same functionality is offered under the new version.
To achieve the old template.fetch(entity) equivalent behaviour, you should call one of the load methods specifying the fetch depth as a parameter.
It’s also worth noting that exec(GraphCallback) and the create…​() methods have been made obsolete by Cypher. Instead, you should now issue a Cypher query to the new execute method to create the nodes or relationships that you need.
Dynamic labels, properties and relationship types are not supported as of this version, server extensions should be considered instead.
from this link https://docs.spring.io/spring-data/neo4j/docs/5.0.0.RELEASE/reference/html/
Could anyone help me in achieving the equivalent solution in
SDN 5.X
Thanks!!!
I took the advice to use the session directly in place of the Neo4jOperations mechanism.
#Autowired
SessionFactory sessionFactory
public void doCustomQuery() {
Session session = sessionFactory.openSession();
Iterable<NodeEntity> nodes = session.query(NodeEntity.class, "MATCH (n) RETURN n", params);
}

Can use spring data neo4j to execute query like Jdbcteamplate?

I'm using JdbcTemplate to execute native Cypher query.
It is easy to make a query such as: jdbcTemplate.execute(String query)
And now when I moving to spring data neo4j, I wonder if there is any interface to execute directly String query like JdbcTemplate did?
There are many options.
Because you are using Java, one option is to make use of OGM (a library that can be used independently or is included as a core dependency of Spring Data Neo4j).
OGM provides a session object that has query() and queryForObject() methods.
More information (and examples) can be found in the OGM reference documentation:
https://neo4j.com/docs/ogm-manual/3.1/reference/#reference:session:loading-entities

Mapping Queries result set to domain objects in SDN 3.3.1.RELEASE

I have created a POC with SDN 3.3.1 in which I have deployed a plugin inside the Neo4j server. The plugin contains domain objects, repositories and controllers.
From my application, I'm making rest calls to the controllers to execute repositories methods and return the response.
The issue is that in my queries, I'm returning multiple nodes and relationships. So, to map the response, I created wrapper classes using #QueryResult, #ResultColumn containing references to domain objects for each query. This is because each query has a different result set.
Since, my application has around 150 such queries I will have to create similar number of intermediate wrapper classes.
This is quite tedious and number of wrapper classes will only increase in future as more and more queries are added.
Is there any smarter way to do this?
I tried to have all of my domain objects as references in a single wrapper class. So that I can use it for any of my queries. But it gives exception if any of the fields in the wrapper class is not present in the query result.
Another issue is that, some of my queries are written to return all different nodes connected to a particular node, e.g,
Match (a)-[rel]->(b)-[tempRel]->(tempNodes) Return b,tempRel,tempNodes
I'm not sure how to map this result set to a wrapper class.
Is there any way to achieve it without refactoring the queries to match indvidual paths?
Regards,
Rahul
Good idea to have it ignore unknown classes and fields in both directions perhaps as an additional annotation on the class can you raise a Spring JIRA issue?
something like this e.g.
#QueryResult(requireFields=false, require=false)
class MyResult {
String name;
int age;
}
but you still have them focused on one area or use-case and not 1 for all 150 use-cases but perhaps 15-30 different ones.

Custom Iterable in Spring Data Neo4j

Can we have custom iterators in Spring Data Neo4j for Node Entities?
I have an existing code which has CustomHashCollection as an iterable. I want to convert the project to use Neo4j. Can I use the custom iterator as it is a private member in most of the NodeEntity classes.
Thanks in advance.
What is different with your Iterable?
As far as I remember there is no custom extensibility for iterable types, so far the JDK collection were good enough.

How to enlist XAResource with existing Transaction?

My use case is:
I have an existing JTA TransactionManager and a Transaction in-flight. I'd like to enlist Neo4j as an XAResource in this Transaction such that it may prepare/commit in proper 2PC.
I'm not seeing a public XAResource implementation in Neo4j; everything seems to be routed through the NioNeoDbPersistenceSource > NeoStoreXaDataSource > NeoStoreXaConnection.NeoStoreXaResource.
Is there a preferred way to enlist Neo4j in JTA Transactions outside those provided by its own TransactionManager? All the test cases I'm finding enlist mock "FakeXAResource"[1]
Appreciated!
S,
ALR
[1] e.g. UseJOTMAsTxManagerIT
OK, I have a solution which I believe is the best that Neo4j can handle, though I'm not thrilled with it. :)
https://gist.github.com/ALRubinger/b584065d0e7da251469a
The idea is this:
1) Implement Neo4j's AbstractTransactionManager
This clunky class is a composite of JTA TransactionManager, Neo4j Lifecycle, and some other methods; it's not completely clear to me what some of these (e.g. "getEventIdentifier()" or "doRecovery()") are supposed to, and the contract feels over-specified. I'm not certain why we'd want lifecycle methods in here for the case where Neo4j is not the authoritative owner of the TransactionManager.
2) Implement Neo4j's TransactionManagerProvider
This will let you create a new instance of your AbstractTransactionManager implementation, but it's bound by the JDK Service SPI, so you must supply a no-arg constructor and find some other intelligent/hacky way of passing contextual information in.
3) Create a META-INF/services/org.neo4j.kernel.impl.transaction.TransactionManagerProvider file, with contents of the FQN of your TransactionManagerProvider impl from step 2)
4) When you create a new GraphDatabaseService, pass in config like:
final GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory().
newEmbeddedDatabaseBuilder(FILE_NAME_STORAGE).setConfig(
GraphDatabaseSettings.tx_manager_impl.name(),
"NAME_OF_YOUR_TXM_PROVIDER")
.newGraphDatabase();
Then you access the TransactionManager using a deprecated API (GraphDatabaseAPI):
// Get at Neo4j's view of the TransactionManager
final TransactionManager tm = ((GraphDatabaseAPI) graphDatabaseService).getDependencyResolver().resolveDependency(TransactionManager.class);
tm.begin();
final Transaction tx = tm.getTransaction();
The real problem I have with this approach is that we have to use the TransactionManager implementation from Neo4j, which is wrapping our real TM. What I want to do is use my TM and enlist Neo4j as an XAResource.
So I still haven't found a way to do that, and judging from the Neo4j test suites I don't think it's possible at the moment with any of their supplied XAResource support.
Absolutely willing and hoping to be corrected! :)
But failing the points I mention above, the attached gist works and shows Neo4j using an external TransactionManager (Narayana, from us at JBoss) as the backing implementation.
S,
ALR

Resources