Nebula版本3.0.0升级至3.3.0,java client查询结果异常

  • nebula 版本:3.30
  • nebula-java 版本:3.0.0(3.3.0也测试过)
  • 部署方式: 分布式
  • 安装方式:DEB
  • 是否为线上版本: N
  • 硬件信息
    • SSD
    • CPU、内存信息 单节点 8core16g
  • 相同查询语句,查询升级后的nebula(3.0.0→3.3.0)后,结果中部分字段返回NULL,在console中查询结果是存在。
    查询语句格式:USE graph_space; MATCH (p1:Tag)-[r:]->(p2:Tag) WHERE id(p1) IN [] AND id(p2) IN [**] RETURN p1.Tag.user_name as sonUserName,p1.Tag.user_database_id as sonUserId,p1.Tag.influencer as sonInfluencer,p1.Tag.website_user as sonWebsiteUser,p2.Tag.user_database_id as parentUserId LIMIT 50000;
    说明:Tag指代的是同一个。
    预期结果:每个字段都会返回对应值
    实际结果:

    尝试在 return 后面添加 p1,结果中的NULL消失,返回结果截图:

访问nebula 3.0.0结果截图:

来把相关的 java 代码和 nebula-console 的执行结果贴一下。

public ResultSet search(String cypher){
        //每次查询前建立连接
//        createConnection(mainConfiguration.getNebula());
        Session session = null;
        try {
            Long startTime = System.currentTimeMillis();
            session = nebulaPool.getSession(mainConfiguration.getNebula().getUsername(), mainConfiguration.getNebula().getPassword(), false);
            ResultSet resultSet = session.execute(cypher);
            Long endTime = System.currentTimeMillis();
            try {
                if ((endTime - startTime) > 2000){
                    //查询时间大于2S,记录日志
                    log.warn("查询时长:{} ms,查询session:{},查询语句:{},",(endTime - startTime), JSON.toJSONString(session.getGraphHost()),cypher);
                }
                if (resultSet.getErrorCode() != ErrorCode.SUCCEEDED.getValue()) {
                    log.error("在host:{},查询nebula异常:{},{},nGql:{}", JSON.toJSONString(session.getGraphHost()),resultSet.getErrorCode(), resultSet.getErrorMessage(), cypher);
                }
            } catch (Exception e) {
                log.error("日志记录失败:" + cypher,e);
            }
            return resultSet;
        } catch (IOErrorException | AuthFailedException | NotValidConnectionException | ClientServerIncompatibleException e) {
            if (Objects.nonNull(session)){
                log.error("在host:{},查询nebula异常,nGql:{}", JSON.toJSONString(session.getGraphHost()), cypher);
            }
        }finally {
            if (Objects.nonNull(session)){
                session.release();
            }
        }
        return null;
}

console截图:

初始化代码

 @Bean
    public NebulaPool nebulaPool(MainConfiguration configuration) throws UnknownHostException {
        NebulaConfiguration nebula = configuration.getNebula();
        String[] hosts = nebula.getHosts();
        NebulaPool pool = new NebulaPool();
        NebulaPoolConfig nebulaPoolConfig = new NebulaPoolConfig();
        nebulaPoolConfig.setMaxConnSize(1000);
        List<HostAddress> hostInfos = new ArrayList<>(hosts.length);
        for (String host : hosts) {
            hostInfos.add(new HostAddress(host,nebula.getPort()));
        }
        boolean init = pool.init(hostInfos, nebulaPoolConfig);
        if (!init){
            throw new BusinessValidationException("NebulaGraph init err !");
        }else {
            log.info("NebulaGraph init Success !");
        }
        return pool;
    }

问题稳定复现吗

是的,我测试了不同的nebula查询,就只发现这种情况下有问题

其他语句会存在这种情况吗?
你的数据是否方便发一下,我们复现一下看看

mach(v:Tag) where v.Tag.parentUserId==“17595489” return v

用client 执行以下这个语句,看是否返回的有null

这个不是null,我刚让数据组的同事用scala的demo跑了一遍,我们是相同jar包,他那有结果,我再对比一下看是哪里有问题,后续我再补充细节

经过对比,发现需要先 “session.execute(“USE graph_space;”);”,然后再执行查询语句,返回结果就正常了,希望哪位大佬可以帮忙解释一下,,

USE graph_space; MATCH (p1:Tag)-[r:**]->(p2:Tag) WHERE id(p1) == '1134954446419505152' RETURN p1.Tag.property as sonUserName limit 1;

一起执行,只要开始查询属性就会返回null,开始是获取节点,就可以获取到数据

你这边有 nebula-studio 或者 nebula-console 安装了么?试试把这个语句放在别的客户端上执行下呢。

执行结果是ok的,就是用java程序访问有异常

1 个赞

测试数据,
edge_demo.txt (13 字节)
tag_demo.txt (34 字节)
建表语句:

CREATE SPACE rel_demo (partition_num = 5, replica_factor = 1, vid_type = FIXED_STRING(30));
CREATE TAG person(user_id string,user_name string);
CREATE EDGE person_rel();

查询语句:

一 session.execute("USE rel_demo;")   
  val set = session.execute("match(p1)-[]->(p2) WHERE id(p1) == '1' RETURN p1.person.user_name as sonUserName limit 1;")(正常)

二 val set = session.execute("USE rel_demo; match(p1)-[]->(p2) WHERE id(p1) == '1' RETURN p1.person.user_name as sonUserName limit 1;")(异常)

你在console中执行一下 下面这个语句:(前提是当前不在rel_demo的space下)
USE rel_demo; match(p1)-[]->(p2) WHERE id(p1) == ‘1’ RETURN p1.person.user_name as sonUserName limit 1;

在console中,不选择space或者选择其它space,会提示一下错误:

你要在console中去执行,不要用studio

那和客户端没关系,是use space + match 语句,@steam 可以去记个issue。
@Groot 你可以先通过拆分 use space和match语句来实现你的功能。