/// <summary> /// Find incoming or outgoing edge by "srcId and _offset" /// Output the edgeObject, as well as the edgeDocId (null for small-degree edges) /// </summary> /// <param name="connection"></param> /// <param name="vertexObject"></param> /// <param name="srcVertexId"></param> /// <param name="edgeOffset"></param> /// <param name="isReverseEdge"></param> /// <param name="edgeObject"></param> /// <param name="edgeDocId"></param> public static void FindEdgeBySourceAndOffset( GraphViewConnection connection, JObject vertexObject, string srcVertexId, long edgeOffset, bool isReverseEdge, out JObject edgeObject, out string edgeDocId) { if (!isReverseEdge) { Debug.Assert((string)vertexObject["id"] == srcVertexId); } JToken edgeContainer = vertexObject[isReverseEdge ? "_reverse_edge" : "_edge"]; if (edgeContainer is JArray) // for small-degree vertexes { if (isReverseEdge) { edgeObject = (from edgeObj in edgeContainer.Children <JObject>() where (string)edgeObj["_srcV"] == srcVertexId where (long)edgeObj["_offset"] == edgeOffset select edgeObj ).FirstOrDefault(); } else { edgeObject = (from edgeObj in edgeContainer.Children <JObject>() where (long)edgeObj["_offset"] == edgeOffset select edgeObj ).FirstOrDefault(); } edgeDocId = null; } else if (edgeContainer is JObject) // for large-degree vertexes { string edgeIdList = string.Join(", ", edgeContainer["_edges"].Children <JObject>().Select(e => $"'{e["id"]}'")); string query; if (isReverseEdge) { query = $"SELECT doc.id, edge\n" + $"FROM doc\n" + $"JOIN edge IN doc._edge\n" + $"WHERE doc.id IN ({edgeIdList})\n" + $" AND (edge._srcV = '{srcVertexId}')\n" + $" AND (edge._offset = {edgeOffset})\n"; } else { query = $"SELECT doc.id, edge\n" + $"FROM doc\n" + $"JOIN edge IN doc._edge\n" + $"WHERE doc.id IN ({edgeIdList})\n" + $" AND (edge._offset = {edgeOffset})\n"; } JObject result = connection.ExecuteQueryUnique(query); edgeDocId = (string)result?["id"]; edgeObject = (JObject)result?["edge"]; } else { throw new Exception($"BUG: edgeContainer should either be JObject or JArray, but now: {edgeContainer?.GetType()}"); } }
/// <summary> /// Find incoming or outgoing edge by "srcId and edgeId" /// Output the edgeObject, as well as the edgeDocId (null for small-degree edges) /// </summary> /// <param name="connection"></param> /// <param name="vertexObject"></param> /// <param name="srcVertexId"></param> /// <param name="edgeId"></param> /// <param name="isReverseEdge"></param> /// <param name="edgeObject"></param> /// <param name="edgeDocId"></param> public static void FindEdgeBySourceAndEdgeId( GraphViewConnection connection, JObject vertexObject, string srcVertexId, string edgeId, bool isReverseEdge, out JObject edgeObject, out string edgeDocId) { if (!isReverseEdge) { Debug.Assert((string)vertexObject[KW_DOC_ID] == srcVertexId); } JToken edgeContainer = vertexObject[isReverseEdge ? KW_VERTEX_REV_EDGE : KW_VERTEX_EDGE]; if (!IsSpilledVertex(vertexObject, isReverseEdge)) { // for small-degree vertexes if (isReverseEdge) { edgeObject = (from edgeObj in edgeContainer.Children <JObject>() where (string)edgeObj[KW_EDGE_SRCV] == srcVertexId where (string)edgeObj[KW_EDGE_ID] == edgeId select edgeObj ).FirstOrDefault(); } else { edgeObject = (from edgeObj in edgeContainer.Children <JObject>() where (string)edgeObj[KW_EDGE_ID] == edgeId select edgeObj ).FirstOrDefault(); } edgeDocId = null; } else // For large-degree vertices // Now the vertex document stores the last(latest) spilled edge document only. //string edgeDocIdList = string.Join(", ", edgeContainer.Children<JObject>().Select(e => $"'{e[KW_DOC_ID]}'")); { const string EDGE_SELECT_TAG = "edge"; string query = $"SELECT doc.{KW_DOC_ID}, {EDGE_SELECT_TAG}\n" + $"FROM doc\n" + $"JOIN {EDGE_SELECT_TAG} IN doc.{KW_EDGEDOC_EDGE}\n" + $"WHERE (doc.{KW_EDGEDOC_ISREVERSE} = {isReverseEdge.ToString().ToLowerInvariant()})\n" + $" AND ({EDGE_SELECT_TAG}.{KW_EDGE_ID} = '{edgeId}')\n"; JObject result = connection.ExecuteQueryUnique(query); edgeDocId = (string)result?[KW_DOC_ID]; edgeObject = (JObject)result?[EDGE_SELECT_TAG]; } }