Gremlin遍历中如何使用顶点自身属性值作为过滤阈值?
问题背景
需要实现顶点过滤逻辑:计算传入经纬度坐标与所有point标签顶点的Haversine大圆距离,过滤掉距离大于顶点自身max_distance属性值的顶点,仅返回符合条件的结果。原有代码中lte比较传入固定值10时运行正常,需要将硬编码阈值替换为每个遍历顶点自身的max_distance属性值。
所有point标签顶点均包含以下属性:
latitude:纬度longitude:经度max_distance:该顶点允许的最大匹配距离
原有实现代码:
r_deg = 0.017453293 e_rad = 6371 def get_points_within_distance(latitude, longitude, r_deg, e_rad): try: _result = n_graph. \ with_side_effect("r_deg", r_deg). \ with_side_effect("e_rad", e_rad). \ with_side_effect("p_lat", latitude). \ with_side_effect("p_lon", longitude). \ V(). \ hasLabel("point"). \ where( project("ladiff", "lodiff", "latitude", "longitude"). by(project("lat").by("latitude"). math("(lat - p_lat) * r_deg")). by(project("lon").by("longitude"). math("(lon - p_lon) * r_deg")). by("latitude"). by("longitude"). math('(sin(ladiff/2))^2 + cos(latitude*r_deg) * cos(p_lat*r_deg) * (sin(lodiff/2))^2'). math('e_rad * (2 * asin(sqrt(_)))'). is_(lte(10)) ). \ value_map(True). \ to_list() except Exception as _e: LOG.error(f"Failed to retrieve points: {_e}.") return return _result
解决方案
原有逻辑的问题在于连续执行math步骤后,遍历流中仅剩余计算出的距离数值,已经丢失当前顶点的属性上下文,无法读取max_distance做动态比较。调整遍历结构,同时保留计算出的距离和顶点自身阈值后再做比对即可,修改后的完整代码如下:
r_deg = 0.017453293 e_rad = 6371 def get_points_within_distance(latitude, longitude, r_deg, e_rad): try: _result = n_graph. \ with_side_effect("r_deg", r_deg). \ with_side_effect("e_rad", e_rad). \ with_side_effect("p_lat", latitude). \ with_side_effect("p_lon", longitude). \ V(). \ hasLabel("point"). \ where( project("dist", "max_dist"). # 内嵌投影计算两点实际Haversine距离 by( project("ladiff", "lodiff", "latitude", "longitude"). by(project("lat").by("latitude"). math("(lat - p_lat) * r_deg")). by(project("lon").by("longitude"). math("(lon - p_lon) * r_deg")). by("latitude"). by("longitude"). math('(sin(ladiff/2))^2 + cos(latitude*r_deg) * cos(p_lat*r_deg) * (sin(lodiff/2))^2'). math('e_rad * (2 * asin(sqrt(_)))') ). # 读取当前顶点自身的max_distance阈值 by("max_distance"). # 逐顶点比较实际距离与自身阈值 where("dist", lte("max_dist")) ). \ value_map(True). \ to_list() except Exception as _e: LOG.error(f"Failed to retrieve points: {_e}.") return return _result
修改点说明
- 外层新增
project("dist", "max_dist"),同时存储两个比对所需的值:dist为经Haversine公式计算出的实际距离,max_dist为当前顶点的max_distance属性 - 移除原有硬编码的
is_(lte(10))判断,替换为where("dist", lte("max_dist")),实现逐顶点动态阈值比对 - 原有Haversine距离计算逻辑完全保留,无需修改公式部分
内容的提问来源于stack exchange,提问作者Jakov
相关产品推荐
相关产品推荐

