Coder Social home page Coder Social logo

jredisgraph's Introduction

license GitHub issues Maven Central Javadocs Codecov Known Vulnerabilities

JRedisGraph

Forum Discord

RedisGraph Java client

Deprecation notice

As of Jedis version 4.2.0, this library is deprecated. Its features have been merged into Jedis. Please either install it from maven or the repo.

Official Releases

  <dependencies>
    <dependency>
      <groupId>com.redislabs</groupId>
      <artifactId>jredisgraph</artifactId>
      <version>2.5.1</version>
    </dependency>
  </dependencies>

Snapshots

  <repositories>
    <repository>
      <id>snapshots-repo</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
  </repositories>

and

  <dependencies>
    <dependency>
      <groupId>com.redislabs</groupId>
      <artifactId>jredisgraph</artifactId>
      <version>2.6.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

Example: Using the Java Client

package com.redislabs.redisgraph;

import com.redislabs.redisgraph.graph_entities.Edge;
import com.redislabs.redisgraph.graph_entities.Node;
import com.redislabs.redisgraph.graph_entities.Path;
import com.redislabs.redisgraph.impl.api.RedisGraph;

import java.util.List;

public class RedisGraphExample {
    public static void main(String[] args) {
        // general context api. Not bound to graph key or connection
        RedisGraph graph = new RedisGraph();

        Map<String, Object> params = new HashMap<>();
        params.put("age", 30);
        params.put("name", "amit");

        // send queries to a specific graph called "social"
        graph.query("social","CREATE (:person{name:'roi',age:32})");
        graph.query("social","CREATE (:person{name:$name,age:$age})", params);
        graph.query("social","MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[:knows]->(b)");

        ResultSet resultSet = graph.query("social", "MATCH (a:person)-[r:knows]->(b:person) RETURN a, r, b");
        while(resultSet.hasNext()) {
            Record record = resultSet.next();
            // get values
            Node a = record.getValue("a");
            Edge r =  record.getValue("r");

            //print record
            System.out.println(record.toString());
        }

        resultSet = graph.query("social", "MATCH p = (:person)-[:knows]->(:person) RETURN p");
        while(resultSet.hasNext()) {
            Record record = resultSet.next();
            Path p = record.getValue("p");

            // More path API at Javadoc.
            System.out.println(p.nodeCount());
        }

        // delete graph
        graph.deleteGraph("social");

        // get connection context - closable object
        try(RedisGraphContext context = graph.getContext()) {
            context.query("contextSocial","CREATE (:person{name:'roi',age:32})");
            context.query("social","CREATE (:person{name:$name,age:$age})", params);
            context.query("contextSocial", "MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[:knows]->(b)");
            // WATCH/MULTI/EXEC
            context.watch("contextSocial");
            RedisGraphTransaction t = context.multi();
            t.query("contextSocial", "MATCH (a:person)-[r:knows]->(b:person{name:$name,age:$age}) RETURN a, r, b", params);
            // support for Redis/Jedis native commands in transaction
            t.set("x", "1");
            t.get("x");
            // get multi/exec results
            List<Object> execResults =  t.exec();
            System.out.println(execResults.toString());

            context.deleteGraph("contextSocial");
        }
    }
}

License

FOSSA Status

jredisgraph's People

Contributors

aviavni avatar bsbodden avatar chayim avatar dependabot[bot] avatar dvirdukhan avatar filipecosta90 avatar gkorland avatar jeffreylovitz avatar lgtm-com[bot] avatar sazzad16 avatar snyk-bot avatar swilly22 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

jredisgraph's Issues

Query does not support backtics

I have some special character (colon) in my query and to escape that cypher language suggests to use backtics as mentioned here to use this character. Howerver, using redisgraph I get following error:

127.0.0.1:6379>  GRAPH.QUERY provenance "MATCH (n:`C:\USERS\TARGET0\JAVA.EXE`)-[:write]->(d) RETURN n,d"
(error) Syntax error at offset 13 near ':'

Get GraphEntity properties map

Hi,

Thanks for this project!

When running a query and getting a node/edge in the response, there is no way of iterating over all the properties. This might be useful when I'm not interested in a set of particular properties but rather in all properties.
I think that exposing the properties map (or at least the keys) should solve this.

How to close the redisgraph connections

Hi Team,

I'm looking for a template how to close the redisgraph connection obtained from the JedisPool to handle the resource leakage. How can we achieve this on JRedisGraph dependency?

Below is an excerpt of the code that gets the RedisGraph API which is used by other classes to execute queries against the database.

@Configuration
public class Config {
   @Bean
   public RedisGraph redisGraph() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password);
      return new RedisGraph(pool);
   }
}

We are then calling the created bean directly to send query to database, this is resulting on resource leakage

@Service
public class Util {
   @Autowired
   private RedisGraph redisGraph; 
 public ResultSet redisGraphApi(String query) {
      ResultSet resultSet = redisGraph.query(graphId, query);
      return resultSet;
   }
}

Unreliable Statistics#propertiesSet

We are running a bunch of updating statements like this:

Statistics statistics = driver.query(graphId, query, params).getStatistics();
return statistics.propertiesSet();

The query variable is

MATCH (n:Service {site:$match_site, name:$match_name, namespace:$match_namespace, env:$match_env}) SET n.service_type=$service_type

and an example of the params variable is

{service_type=aurora-mysql, match_namespace=monitoring, match_site=dev, match_env=dev, match_name=aurora-mysql}

I assume if there is a match, the above code should return 1, and if there is no match, it should return 0.

Upon testing, I realize the return value is not reliable at all. Most of the time it returns 0 even though there is a match, so I wonder whether it only returns 1 if the update to service_type property actually changes the value. But then I noticed that in the cases it returns 1, there is a match but there is no change to the service_type property. In summary, neither 1 nor 0 means what I thought it is.

Can someone help explain?

two suggestion to RedisGraphAPITest

  1. writing error

81 line:

ResultSet resultSet = api.query("social", "MATCH (a:Person), (b:Person) WHERE (a.name = 'roi' AND b.name='amit')  CREATE (a)-[:Knows]->(a)"); // guess you want to say a-knows-b
  1. log4j missing
    run test will complain no slf4 default implementation.
    I add a dependency to fix it:
    <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.6</version> </dependency>

Create a new vertex and return its id

When creating a new vertex is it possible to get the id of the newly created vertex. I've tried the following but it throws a JedisDataException.

ResultSet rs = api.query( "CREATE (p:person{name:'rois', age:32}) RETURN ID(p))");

Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: Syntax error at offset 46 near 'RETURN'
at redis.clients.jedis.Protocol.processError(Protocol.java:131)
at redis.clients.jedis.Protocol.process(Protocol.java:165)
at redis.clients.jedis.Protocol.read(Protocol.java:219)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:309)
at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:276)
at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:280)
at com.redislabs.redisgraph.RedisGraphAPI.query(RedisGraphAPI.java:58)

What's the correct way to do this?

Rename packages with `_` in their names

Remove underscores in the packages/folders below (suggestions added)
src/main/java/com/redislabs/redisgraph/graph_entities ==> src/main/java/com/redislabs/redisgraph/entities
src/main/java/com/redislabs/redisgraph/impl/graph_cache ==> src/main/java/com/redislabs/redisgraph/impl/cache

Does MULTI/EXEC support CREATE queries

It seems like MULTI/EXEC doesn't support CREATE queries, is this normal, or am I doing something wrong?

Code sample (Kotlin):

redisGraph.context.use { context ->
  context.multi().use { tx ->
    tx
    .query(
       "testGraph",
       """
           CREATE (:VARIABLE {id:${"$"}id})
       """.trimIndent(),
       mapOf("id" to "test")
    )
    tx.exec()
  }
}

Redis Graph 1.0.6 not working

Hey chaps

I'm trying to run the example before version 2.0.0, and it just doesn't work.

Steps to reproduce:

  1. Spin up redis graph container

docker run -d --name redis-p 6379:6379 redislabs/redisgraph

  1. Import JRedis 1.0.6

<dependencies> <dependency> <groupId>com.redislabs</groupId> <artifactId>jredisgraph</artifactId> <version>1.0.6</version> </dependency> </dependencies>

  1. Copy example in repository readme
public class RedisGraphExample {
	public static void main(String[] args) {

		RedisGraphAPI api = new RedisGraphAPI("social");

		api.query("CREATE (:person{name:'roi',age:32})");
		api.query("CREATE (:person{name:%s,age:%d})", "amit", 30);

		api.query("MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[:knows]->(b)");

		ResultSet resultSet = api.query("MATCH (a:person)-[:knows]->(b:person) RETURN a, b");

		while(resultSet.hasNext()){
			Record record = resultSet.next();
			System.out.println(record.getString("a.name"));
		}
	}
}

Issues:

  1. This line does not work as t here is no query method with more than one argument api.query("CREATE (:person{name:%s,age:%d})", "amit", 30);

  2. By commenting out the above line, we can now attempt to run the code which returns the following error:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.rangeCheck(ArrayList.java:657) at java.util.ArrayList.get(ArrayList.java:433) at com.redislabs.redisgraph.impl.ResultSetImpl.<init>(ResultSetImpl.java:24) at com.redislabs.redisgraph.RedisGraphAPI.query(RedisGraphAPI.java:58) at Main.main(Main.java:11)

Enable TCK integration with Scala hook

As described in the openCypher documentation, by exposing a conformant API we can integrate with and run the TCK more directly than the Cucumber->Behave approach used currently.

This would have a few advantages, including accessing the TCK as a Maven dependency, simpler reporting, and fewer custom steps.

This is in the nice-to-have category - not pressing, but worth keeping in mind!

Property data corruption after graph rebuild

RedisGraph version: 2.2.6
JRedisGraph version: 2.1.0

For simplicity, let's say we have two Java services talking to a RedisGraph server: one called GraphBuilder, the other called GraphQuerier. They both use JRedisGraph client. Our GraphBuilder has a timer task that builds a graph once every minute. We are using MERGE command, so it's essentially a timer task that keeps "upserting" the graph.

Everything is on K8s. When the Redis server crashes, its pod will be restarted, and the graph will be gone, but the GraphBuilder will rebuild the graph in no time. When this happens, queries ran on the GraphQuerier can produce corrupted data. Particularly the property names are messed up.

For instance, if the GraphQuerier has not been restarted after Redis crash, it will print a list of properties with property names all messed up:

properties={name=Service, component=String, instance=String, memory_limits=String, pod=workload | deployment | statefulset | daemonset | replicaset, cpu_limits=String, access_mode=String, _created=1602617008984, _updated=1602617495780}

But if we restart the GraphQuerier, or deploy a new GraphQuerier pod, and query the same node on the same graph, we will get the correct result:

properties={name=Service, app=String, kube_service=String, namespace=String, lookup_workload=workload | deployment | statefulset | daemonset | replicaset, workload=String, workload_type=String, _created=1602617008984, _updated=1602617495780}

Note for some properties, we are storing Java data types like String as the values, so don't be confused there.

The query we run to fetch the data is very simple, like

MATCH (n:EntityType {name:$param0}) WHERE (n._updated >= $param1 AND n._created <= $param2) RETURN n

Is it that JRedisGraph client has some form of cached mapping from property ids to property names? If the graph is rebuilt, the mapping will be out-of-date.

We don't have a way to always restart all our services whenever the Redis restarts. So this kind of data corruption cracks the foundation our software is built on.

Extend API to have query builders

Have a builder pattern API which allows executing query without writing directly writing Cypher.
Support CRUD API to nodes and relationships via those builder objects.

Exception in quoteString for empty string

This is the culprit:

If an empty string is passed as a parameter, the code tries to access the 0th character, which fails.

Workaround: use "\"\"" as parameter (i.e. a string that contains only two quotes).

(NB: I didn't send a PR because I'm not completely sure about the semantics of the the quoteString method. Should it escape characters or not?)

How do i connect to a secure redis instance?

No option provided in the RedisGraphAPI constructor to pass auth.

Executing a query fails with following error on an redis instance with auth enabled:
Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
at redis.clients.jedis.Protocol.processError(Protocol.java:131)
at redis.clients.jedis.Protocol.process(Protocol.java:165)
at redis.clients.jedis.Protocol.read(Protocol.java:219)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:309)
at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:276)
at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:280)
at com.redislabs.redisgraph.RedisGraphAPI.query(RedisGraphAPI.java:47)

Maven Build Warning

โžœ mvn clean test
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.redislabs:jredisgraph:jar:2.3.0-SNAPSHOT
[WARNING] 'dependencies.dependency.version' for org.junit.jupiter:junit-jupiter:jar is either LATEST or RELEASE (both of them are being deprecated) @ line 76, column 22
[WARNING] 'dependencies.dependency.version' for org.junit.jupiter:junit-jupiter:jar is either LATEST or RELEASE (both of them are being deprecated) @ line 82, column 22
[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: org.junit.jupiter:junit-jupiter:jar -> duplicate declaration of version RELEASE @ line 79, column 21
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]

Path Query gives ArrayOutOfBoundsException with redisgraph:edge docker version

When running a query like:

"MATCH p=(n:Container)<-[*0..10]-(m) WHERE n.name='c0' AND (n._updated >= 100000 AND n._created <= 100000) RETURN p"

It looks like we are intermittently getting this exception only with the newest redisgraph edge version:

Index -2 out of bounds for length 1
java.lang.ArrayIndexOutOfBoundsException: Index -2 out of bounds for length 1
	at java.base/java.util.concurrent.CopyOnWriteArrayList.elementAt(CopyOnWriteArrayList.java:385)
	at java.base/java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:398)
	at com.redislabs.redisgraph.impl.graph_cache.GraphCacheList.getCachedData(GraphCacheList.java:45)
	at com.redislabs.redisgraph.impl.graph_cache.GraphCache.getLabel(GraphCache.java:30)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializeNode(ResultSetImpl.java:148)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializeScalar(ResultSetImpl.java:240)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializeArray(ResultSetImpl.java:262)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializeScalar(ResultSetImpl.java:238)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializePath(ResultSetImpl.java:253)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.deserializeScalar(ResultSetImpl.java:244)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.parseResult(ResultSetImpl.java:90)
	at com.redislabs.redisgraph.impl.resultset.ResultSetImpl.<init>(ResultSetImpl.java:55)
	at com.redislabs.redisgraph.impl.api.ContextedRedisGraph.sendQuery(ContextedRedisGraph.java:53)
	at com.redislabs.redisgraph.impl.api.RedisGraph.sendQuery(RedisGraph.java:68)
	at com.redislabs.redisgraph.impl.api.AbstractRedisGraph.query(AbstractRedisGraph.java:39)
	at ai.asserts.model.redis.RedisKGraph.getEntityWithUplinks(RedisKGraph.java:178)
	at ai.asserts.model.graph.KGraphTest$UplinkMatchTest.redis_test(KGraphTest.java:93)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:413)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:834)

We suspect the newer version triggered the issue in the client, but can't be 100%. Currently trying to deconstruct the series of queries that surfaced this as it seems to only occur with a specific ordering of queries. Hoping that maybe there is something known on your end.

All other previous versions didn't show this issue. Thanks for any help.

@DvirDukhan

Timestamp values are deserialized into Integer

Steps to reproduce:

  • run a Cypher query to create a node, with a timestamp property created like
    MERGE (n:Foo) ON CREATE SET n.created=timestamp()
  • If you check out the graph in RedisInsight, you can see the created being a Unix timestamp
  • If you use JRedisGraph client to retrieve the node, you will notice that the created property is deserialized into an integer. Because a 64-bit Unix timestamp cannot fit into a 32-bit Java integer, it overflows and yields some strange integer values.

RedisGraph says the numeric types could be either 64-bit doubles and 64-bit signed integer. In Java, 64-bit signed Integer should be Long, instead of Integer. The ResultSetScalarTypes should really contain VALUE_LONG instead of VALUE_INTEGER. Likewise, In ResultSetImpl#deserializeScalar, we shouldn't cast the Long to an Integer.

How to use MULTI/EXEC?

Thanks for this project.

Seeing that RedisGraph is a Redis module, I understand that we can use the MULTI/EXEC commands to query the graph as well.
How can this be done using JRedisGraph?

ResultSet parse to Tree Struct

I have some entities in my graph, such as Device which is own of an Organization, Software which is installed on a Device, etc

Screen Shot 2021-01-13 at 3 14 17 PM
Screen Shot 2021-01-13 at 2 56 35 PM

when I query by "MATCH p = (o:Organization) - [*] - (s) return o as primary, s as target, nodes(p) as nodes, relationships(p) as edges' cypher sql,

finally, I want to get a tree struct like this, maybe like graphQL result.

GraphNode: {
	id: "org1",
	label: "Organization",
	property: {
		name: 'apple',
                 ...
	},
	children: [
	        GraphNode2,
		{
                    id: "dev01",
                    label: "Device",
                    property: {
                       name: 'dev01',
                       .....
                   }
                   children: [
                        GraphNode4
                   ]
                }
              ....
	]
}

does anyone have same work? or some suggestions? thx

MERGE Relationship

MATCH(a:person{name:'roi'}), (b:person{name:'amit'}) MERGE (a)-[:knows]->(b) throws
(error) Syntax error at offset 59 near 'MERGE

Q. Does CREATE, in this instance using JRedisGraph, behavior as specified in Cypher, it will re-create the relationship each time?

Client not working with latest RedisGraph!!!!!!

JRedisGraph client does not work since RedisGraph results sets were reworked (as per RedisGraph/RedisGraph@777da81).

The problem is that the return values now contain (nil) for null values and a similar format e.g. (integer) 1500 for primitive types.

Example stack trace, coming from a result set with integers in:

	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at com.redislabs.redisgraph.impl.ResultSetImpl.<init>(ResultSetImpl.java:43)
	at com.redislabs.redisgraph.RedisGraphAPI.query(RedisGraphAPI.java:58)
	at williamhill.retail.dds.graphviewer.redis.RedisGraphManualTest.testPrematchEventsRequestAndResponse(RedisGraphManualTest.java:111)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

Exactly one relationship type must be specified for CREATE - Example

Hi, I am running your example with 1.0.3 version, I am getting the following error while running the query:

api.query("MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[knows]->(a)")

Error:
Exactly one relationship type must be specified for CREATE

Question: How to add indexes?

I have tried to add an index programmatically using jredisgraph (version 1.0.3), but it crashes with an IndexOutOfBoundsException (see below). Is this the right/only way to add indexes from code?

The exception occurs when executing following code. It appears to occur because the return value from the server has only one entry, but 2 are expected.

Code:

    RedisGraphAPI graphApi = new RedisGraphAPI("graphKey");
    graphApi.query("CREATE INDEX on :SELECTION(id)");

Stack trace:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
	at java.util.ArrayList.rangeCheck(ArrayList.java:653)
	at java.util.ArrayList.get(ArrayList.java:429)
	at com.redislabs.redisgraph.impl.ResultSetImpl.<init>(ResultSetImpl.java:23)
	at com.redislabs.redisgraph.RedisGraphAPI.query(RedisGraphAPI.java:58)
        ....

Support for point() type and function

It appears that the java graph library ( com.redislabs.redisgraph.impl.api.RedisGraph ) cannot handle point() types.

Query: match (s:Shopper {id: 3}) return s graph: recommendations
Records returned from query: match (s:Shopper {id: 3}) return s
[Record] Key: s Value: Node{labels=[Shopper], id=4002, propertyMap={country=Property{name='country', value=Canada}, name=Property{name='name', value=David Rugrat}, id=Property{name='id', value=3}}}
Query: match (s:Shopper {id: 1}) return s graph: recommendations

Exception in thread "main" com.redislabs.redisgraph.exceptions.JRedisGraphCompileTimeException: redis.clients.jedis.exceptions.JedisDataException: Unrecognized response type
	at com.redislabs.redisgraph.impl.api.ContextedRedisGraph.sendQuery(ContextedRedisGraph.java:59)
	at com.redislabs.redisgraph.impl.api.RedisGraph.sendQuery(RedisGraph.java:68)
	at com.redislabs.redisgraph.impl.api.AbstractRedisGraph.query(AbstractRedisGraph.java:37)

redis-cli handles the point type:

127.0.0.1:10005> GRAPH.QUERY "recommendations" "match (s:Shopper {id: 3}) return s"
1) 1) "s"
2) 1) 1) 1) 1) "id"
            2) (integer) 4002
         2) 1) "labels"
            2) 1) "Shopper"
         3) 1) "properties"
            2) 1) 1) "id"
                  2) (integer) 3
               2) 1) "name"
                  2) "David Rugrat"
               3) 1) "country"
                  2) "Canada"
3) 1) "Cached execution: 1"
   2) "Query internal execution time: 0.202800 milliseconds"
127.0.0.1:10005> GRAPH.QUERY "recommendations" "match (s:Shopper {id: 1}) return s"
1) 1) "s"
2) 1) 1) 1) 1) "id"
            2) (integer) 4000
         2) 1) "labels"
            2) 1) "Shopper"
         3) 1) "properties"
            2) 1) 1) "id"
                  2) (integer) 1
               2) 1) "name"
                  2) "David Hoppytail"
               3) 1) "country"
                  2) "Canada"
               4) 1) "geo_point"
                  2) "point({latitude:51.964802, longitude:-88.150902})"
3) 1) "Cached execution: 1"
   2) "Query internal execution time: 0.185100 milliseconds"

Add multi label support

Latest version of RedisGraph support node with multiple labels this needs to be reflected in the client
when creating a node and when parsing a result that contains node

redis.clients.jedis.exceptions.JedisConnectionException is reported when executing the Cypher queries.

Hello, I discovered that when I executed the queries in the attached java file, an exception occurred:
redisgraph.zip

Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
at redis.clients.jedis.util.RedisInputStream.readByte(RedisInputStream.java:43)
at redis.clients.jedis.Protocol.process(Protocol.java:158)
at redis.clients.jedis.Protocol.read(Protocol.java:223)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:352)
at redis.clients.jedis.Connection.getOne(Connection.java:330)
at redis.clients.jedis.Jedis.sendCommand(Jedis.java:4559)
at com.redislabs.redisgraph.impl.api.ContextedRedisGraph.sendQuery(ContextedRedisGraph.java:52)
at com.redislabs.redisgraph.impl.api.RedisGraph.sendQuery(RedisGraph.java:68)
at com.redislabs.redisgraph.impl.api.AbstractRedisGraph.query(AbstractRedisGraph.java:63)
at RedisGraphExample.main(RedisGraphExample.java:32)

But if I comment out some of the queries, no error will be reported. And if these queries do not contain WHERE clauses, no error will be reported. I wonder if it is a bug. Thanks a lot!

RedisGraph Version: 2.4.11 Docker
Operating System: Windows 11
API: Cypher/Java API
JRedisGraph Version: 2.5.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.