手机之间的通联关系使用时间过滤如何使用自定义函数实现
发布于 6 年前 作者 crazyyanchao 2215 次浏览 来自 问答
MATCH p=(phone1:手机号)-[r3:通联]-(phone3:手机号) WHERE r3.MyFunction(startTime,stopTime)  RETURN p

上述查询的关系 r3 上面有个属性如下: dateHistory: 2018-03-25 17:49:39,2018-03-22 23:13:56,2018-03-05 21:13:05,2018-03-01 17:01:25,2018-03-01 10:48:08,2018-03-01 10:48:03,2018-03-01 10:48:02 是时间用逗号分割拼接的一个STRING存进去的,现在需要用时间进行过滤,如何用时间段进行过滤关系?如果是用自定义函数实现过滤能否提供一个参考? 例如:我需要过滤2018-01-25 17:49:39 ~ 2018-03-22 23:13:56时间段内有通联关系的手机号码,如何实现?

TimeZone3.png 能否吧匹配到的时间拿出来重置关系的属性?

3 回复

MATCH p=(n:手机号)-[r:通联]-(m:手机号) WHERE n.name=‘13910317532’ AND m.name=‘13910272362’ AND casia.apoc.matchTimeZone({timeList:r.dateHistory,startTime:‘2018-03-06 20:57:26’,stopTime:‘2018-03-06 20:57:26’})=1 RETURN p 自定义函数casia.apoc.matchTimeZone返回0表示不满足时间区间,返回1表示满足时间区间。

//自定义函数
 @UserFunction(name = "casia.apoc.matchTimeZone")
    public Number matchTimeZone(@Name("timePara") Map<String, String> mapPara) {
        String startTime = mapPara.get("startTime");
        String stopTime = mapPara.get("stopTime");
        DateHandle dateHandle = new DateHandle();
        long startTimeLong = dateHandle.dateToMillisecond(startTime);
        long stopTimeLong = dateHandle.dateToMillisecond(stopTime);
        String timeListString = mapPara.get("timeList");
        String[] timeArray = timeListString.split(",");
        String time;
        long timeLong;
        int size = timeArray.length;
        for (int i = 0; i < size; i++) {
            time = timeArray[i];
            timeLong = dateHandle.dateToMillisecond(time);
            if (startTimeLong <= timeLong && timeLong <= stopTimeLong) {
                return 1;   // 符合时间区间返回1
            }
        }
        return 0;   // 不符合时间区间返回0
    }
//测试
@Test
    public void matchTimeZone() throws Exception {
        GraphDatabaseService db = neo4j.getGraphDatabaseService();
        try (Transaction tx = db.beginTx()) {
            String dateHistory = "2018-03-25 17:49:39,2018-03-22 23:13:56,2018-03-05 21:13:05,2018-03-01 17:01:25,2018-03-01 10:48:08,2018-03-01 10:48:03,2018-03-01 10:48:02";
            Map<String, String> map = new HashMap<>();
            map.put("timeList", dateHistory);
            map.put("startTime", "2018-03-25 10:49:39");
            map.put("stopTime", "2018-03-25 20:49:39");
            Map<String, Object> params = new HashMap<>();
            params.put("paras", map);
            Result result = db.execute("RETURN zdr.apoc.matchTimeZone({paras}) as value", params);
            int size = (int) result.next().get("value");
        }
    }

上面是目前实现的方法,是否有更好的方式?

建议从数据模型的角度考虑. 比如将每次通讯作为一个通联关系,查询时按通联关系上时间属性过滤,这样查询更高效. 个人认为在资源允许的情况下,用空间换时间

回到顶部