如何将OrientDB查询改写为Gremlin(TinkerPop)及查询日志实现
问题描述
我有一条简单的OrientDB查询:
MATCH {class:SomeObj, as:obj, Where:( (outE('SomeEdge')[in=#74:2].StringValue="STRINNNGGG") and (outE('SomeEdge')[in=#75:2].NumberValue=333) ) } RETURN obj
该查询在OrientDB Studio中返回一条记录。我尝试在Java中使用Gremlin执行该查询但未成功,尝试的两种查询分别抛出NoSuchElementException和ClassCastException。
请问如何将上述OrientDB查询改写为Gremlin?此外,我希望查看Gremlin构建的查询,具体需求如下:
- 在OrientDB社区版服务器上记录所有执行的查询(类似PostgreSQL中
data/postgresql.conf的log_statement=ALL); - 在gremlin-server上记录所有查询;
- 在Java API中打印构建好的查询,例如
g.V().hasLabel("SomeObject").toString()输出select from SomeObject。恳请告知查询打印的方法。
解决方案
一、OrientDB MATCH查询转Gremlin
原查询逻辑是:找到SomeObj类的节点,该节点通过SomeEdge边分别连接到ID为#74:2和#75:2的节点,且对应边的StringValue为"STRINNNGGG"、NumberValue为333。对应的Gremlin查询如下:
g.V().hasLabel('SomeObj') .where( __.outE('SomeEdge') .has('StringValue', 'STRINNNGGG') .inV().hasId('#74:2') ) .where( __.outE('SomeEdge') .has('NumberValue', 333) .inV().hasId('#75:2') )
如果OrientDB对ID格式有特殊处理(比如不需要前缀#),可调整hasId的参数为'74:2',具体以实际存储格式为准。
二、查询日志与打印方法
1. OrientDB社区版记录所有查询
修改OrientDB的orientdb-server-config.xml配置文件:
- 找到日志配置区域,添加或调整以下logger节点,开启查询日志:
<logger name="com.orientechnologies.orient.core.sql" level="FINE"/> <logger name="com.orientechnologies.orient.core.command" level="FINE"/> - 同步调整日志输出配置(如
log4j.properties),确保上述logger的输出被启用:
之后所有执行的SQL、Gremlin查询都会被记录到指定日志文件中。log4j.logger.com.orientechnologies.orient.core.sql=INFO, file log4j.logger.com.orientechnologies.orient.core.command=INFO, file
2. Gremlin-Server记录所有查询
修改Gremlin-Server的gremlin-server.yaml配置文件:
- 添加查询日志拦截器:
interceptors: - className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessorInterceptor config: log: true - 调整日志配置(如
log4j.properties),设置Gremlin-Server的日志级别:
这样所有发送到Gremlin-Server的查询都会被记录。log4j.logger.org.apache.tinkerpop.gremlin.server=INFO, serverLog
3. Java API中打印Gremlin查询
Gremlin的Traversal对象默认toString()会输出Gremlin语句本身,若需要转换为OrientDB对应的SQL语句,可使用OrientDB的Gremlin翻译器:
import com.orientechnologies.orient.core.gremlin.OGremlinHelper; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*; // 构建Gremlin遍历 Traversal traversal = g.V().hasLabel("SomeObj") .where(outE("SomeEdge").has("StringValue", "STRINNNGGG").inV().hasId("#74:2")) .where(outE("SomeEdge").has("NumberValue", 333).inV().hasId("#75:2")); // 转换为OrientDB SQL String sql = OGremlinHelper.get().translateTraversal(traversal); System.out.println(sql);
执行后会输出对应的OrientDB SQL语句,满足你期望的格式需求。
内容的提问来源于stack exchange,提问作者yasuro
相关产品推荐
相关产品推荐

