private void UpdateNodeProperties( Dictionary <string, JObject> documentsMap, string vertexId, JObject vertexDocObject, List <Tuple <WValueExpression, WValueExpression, int> > propList, UpdatePropertyMode mode) { VertexField vertexField = this.Connection.VertexCache.GetVertexField(vertexId); // Drop all non-reserved properties if (propList.Count == 1 && !propList[0].Item1.SingleQuoted && propList[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) && !propList[0].Item2.SingleQuoted && propList[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase)) { List <string> toBeDroppedPropertiesNames = GraphViewJsonCommand.DropAllNodeProperties(vertexDocObject); foreach (var propertyName in toBeDroppedPropertiesNames) { vertexField.VertexProperties.Remove(propertyName); } } else { foreach (var t in propList) { WValueExpression keyExpression = t.Item1; WValueExpression valueExpression = t.Item2; if (mode == UpdatePropertyMode.Set) { JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(vertexDocObject, keyExpression, valueExpression); if (updatedProperty == null) { vertexField.VertexProperties.Remove(keyExpression.Value); } else { vertexField.UpdateVertexProperty(updatedProperty.Name, updatedProperty.Value.ToString(), JsonDataTypeHelper.GetJsonDataType(updatedProperty.Value.Type)); } } else { throw new NotImplementedException(); } } } documentsMap[vertexId] = vertexDocObject; }
internal override RawRecord DataModify(RawRecord record) { long edgeOffset = long.Parse(record[this._edgeOffsetIndex].ToValue); string srcVertexId = record[this._srcVertexIdIndex].ToValue; JObject srcVertexObject = this.Connection.RetrieveDocumentById(srcVertexId); string outEdgeDocId; JObject outEdgeObject; EdgeDocumentHelper.FindEdgeBySourceAndOffset( this.Connection, srcVertexObject, srcVertexId, edgeOffset, false, out outEdgeObject, out outEdgeDocId); if (outEdgeObject == null) { // TODO: Is there something wrong? Debug.WriteLine($"[UpdateEdgePropertiesOperator] The edge does not exist: vertexId = {srcVertexId}, edgeOffset = {edgeOffset}"); return(null); } string sinkVertexId = (string)outEdgeObject["_sinkV"]; JObject sinkVertexObject; string inEdgeDocId; JObject inEdgeObject; if (sinkVertexId.Equals(srcVertexId)) { sinkVertexObject = srcVertexObject; // NOTE: Must not use DeepClone() here! } else { sinkVertexObject = this.Connection.RetrieveDocumentById(sinkVertexId); } EdgeDocumentHelper.FindEdgeBySourceAndOffset( this.Connection, sinkVertexObject, srcVertexId, edgeOffset, true, out inEdgeObject, out inEdgeDocId); VertexField srcVertexField = this.Connection.VertexCache.GetVertexField(srcVertexId); VertexField sinkVertexField = this.Connection.VertexCache.GetVertexField(sinkVertexId); EdgeField outEdgeField = srcVertexField.AdjacencyList.GetEdgeField(srcVertexId, edgeOffset); EdgeField inEdgeField = sinkVertexField.RevAdjacencyList.GetEdgeField(srcVertexId, edgeOffset); // Drop all non-reserved properties if (this.PropertiesToBeUpdated.Count == 1 && !this.PropertiesToBeUpdated[0].Item1.SingleQuoted && this.PropertiesToBeUpdated[0].Item1.Value.Equals("*", StringComparison.OrdinalIgnoreCase) && !this.PropertiesToBeUpdated[0].Item2.SingleQuoted && this.PropertiesToBeUpdated[0].Item2.Value.Equals("null", StringComparison.OrdinalIgnoreCase)) { List <string> toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(outEdgeObject); foreach (var propertyName in toBeDroppedProperties) { outEdgeField.EdgeProperties.Remove(propertyName); } toBeDroppedProperties = GraphViewJsonCommand.DropAllEdgeProperties(inEdgeObject); foreach (var propertyName in toBeDroppedProperties) { inEdgeField.EdgeProperties.Remove(propertyName); } } else { foreach (Tuple <WValueExpression, WValueExpression, int> tuple in this.PropertiesToBeUpdated) { WValueExpression keyExpression = tuple.Item1; WValueExpression valueExpression = tuple.Item2; if (this.Mode == UpdatePropertyMode.Set) { // Modify edgeObject (update the edge property) JProperty updatedProperty = GraphViewJsonCommand.UpdateProperty(outEdgeObject, keyExpression, valueExpression); // Update VertexCache if (updatedProperty == null) { outEdgeField.EdgeProperties.Remove(keyExpression.Value); } else { outEdgeField.UpdateEdgeProperty(updatedProperty.Name, updatedProperty.Value.ToString(), JsonDataTypeHelper.GetJsonDataType(updatedProperty.Value.Type)); } // Modify edgeObject (update the edge property) updatedProperty = GraphViewJsonCommand.UpdateProperty(inEdgeObject, keyExpression, valueExpression); // Update VertexCache if (updatedProperty == null) { inEdgeField.EdgeProperties.Remove(keyExpression.Value); } else { inEdgeField.UpdateEdgeProperty(updatedProperty.Name, updatedProperty.Value.ToString(), JsonDataTypeHelper.GetJsonDataType(updatedProperty.Value.Type)); } } else { throw new NotImplementedException(); } } } // Interact with DocDB to update the property EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, srcVertexObject, outEdgeDocId, false, outEdgeObject); EdgeDocumentHelper.UpdateEdgeProperty(this.Connection, sinkVertexObject, inEdgeDocId, true, inEdgeObject); // // Drop edge property // if (this.PropertiesToBeUpdated.Any(t => t.Item2 == null)) { return(null); } return(record); }
public FieldObject Terminate() { if (this.subgraphState.graph != null) { return(this.subgraphState.graph); } if (this.subgraphState.vertexIds.Any()) { // this API would modify the parameter, so deep copy it first. List <VertexField> vertices = this.subgraphState.command.Connection.CreateDatabasePortal() .GetVerticesByIds(new HashSet <string>(this.subgraphState.vertexIds), this.subgraphState.command, null, true); List <string> vertexGraphSON = new List <string>(); foreach (VertexField vertexField in vertices) { JObject vertex = new JObject { new JProperty("type", "vertex"), new JProperty("id", vertexField.VertexMetaProperties[KW_DOC_ID].PropertyValue) }; Debug.Assert(vertexField.VertexMetaProperties.ContainsKey(KW_VERTEX_LABEL)); if (vertexField.VertexMetaProperties[KW_VERTEX_LABEL] != null) { vertex.Add(new JProperty("label", vertexField.VertexMetaProperties[KW_VERTEX_LABEL].PropertyValue)); } // Add in Edges JObject inE = new JObject(); if (vertexField.RevAdjacencyList != null && vertexField.RevAdjacencyList.AllEdges.Any()) { var groupByLabel = vertexField.RevAdjacencyList.AllEdges.GroupBy(e => e.Label); foreach (var g in groupByLabel) { string edgelLabel = g.Key; JArray group = new JArray(); foreach (EdgeField edgeField in g) { string edgeId = edgeField.EdgeProperties[KW_EDGE_ID].ToValue; if (!this.subgraphState.edgeIds.Contains(edgeId)) { continue; } JObject edge = new JObject { new JProperty("id", edgeField.EdgeProperties[KW_EDGE_ID].ToValue), new JProperty("outV", edgeField.OutV) }; // Add edge properties JObject properties = new JObject(); foreach (string propertyName in edgeField.EdgeProperties.Keys) { switch (propertyName) { case KW_EDGE_ID: case KW_EDGE_LABEL: case KW_EDGE_SRCV: case KW_EDGE_SINKV: case KW_EDGE_SRCV_LABEL: case KW_EDGE_SINKV_LABEL: case KW_EDGE_SRCV_PARTITION: case KW_EDGE_SINKV_PARTITION: continue; default: break; } properties.Add(new JProperty(propertyName, JsonDataTypeHelper.GetStringFieldData(edgeField.EdgeProperties[propertyName].PropertyValue, edgeField.EdgeProperties[propertyName].JsonDataType))); } edge.Add(new JProperty("properties", properties)); group.Add(edge); } if (group.Count != 0) { inE.Add(edgelLabel, group); } } } if (inE.Count != 0) { vertex.Add(new JProperty("inE", inE)); } // Add out Edges JObject outE = new JObject(); if (vertexField.AdjacencyList != null && vertexField.AdjacencyList.AllEdges.Any()) { var groupByLabel = vertexField.AdjacencyList.AllEdges.GroupBy(e => e.Label); foreach (var g in groupByLabel) { string edgelLabel = g.Key; JArray group = new JArray(); foreach (EdgeField edgeField in g) { string edgeId = edgeField.EdgeProperties[KW_EDGE_ID].ToValue; if (!this.subgraphState.edgeIds.Contains(edgeId)) { continue; } JObject edge = new JObject { new JProperty("id", edgeField.EdgeProperties[KW_EDGE_ID].ToValue), new JProperty("inV", edgeField.InV) }; // Add edge properties JObject properties = new JObject(); foreach (string propertyName in edgeField.EdgeProperties.Keys) { switch (propertyName) { case KW_EDGE_ID: case KW_EDGE_LABEL: //case KW_EDGE_OFFSET: case KW_EDGE_SRCV: case KW_EDGE_SINKV: case KW_EDGE_SRCV_LABEL: case KW_EDGE_SINKV_LABEL: case KW_EDGE_SRCV_PARTITION: case KW_EDGE_SINKV_PARTITION: continue; default: break; } properties.Add(new JProperty(propertyName, JsonDataTypeHelper.GetStringFieldData(edgeField.EdgeProperties[propertyName].PropertyValue, edgeField.EdgeProperties[propertyName].JsonDataType))); } edge.Add(new JProperty("properties", properties)); group.Add(edge); } if (group.Count != 0) { outE.Add(edgelLabel, group); } } } if (outE.Count != 0) { vertex.Add(new JProperty("outE", outE)); } // Add vertex properties JObject vertexProperties = new JObject(); foreach (KeyValuePair <string, VertexPropertyField> kvp in vertexField.VertexProperties) { string propertyName = kvp.Key; Debug.Assert(!VertexField.IsVertexMetaProperty(propertyName), "Bug!"); Debug.Assert(!(propertyName == KW_VERTEX_EDGE || propertyName == KW_VERTEX_REV_EDGE), "Bug!"); JArray propertyArray = new JArray(); foreach (VertexSinglePropertyField vsp in kvp.Value.Multiples.Values) { JObject property = new JObject { new JProperty("id", vsp.PropertyId), new JProperty("value", JsonDataTypeHelper.GetStringFieldData(vsp.PropertyValue, vsp.JsonDataType)) }; if (vsp.MetaProperties.Count > 0) { JObject metaProperties = new JObject(); foreach (KeyValuePair <string, ValuePropertyField> metaKvp in vsp.MetaProperties) { string key = metaKvp.Key; ValuePropertyField value = metaKvp.Value; metaProperties.Add(new JProperty(key, JsonDataTypeHelper.GetStringFieldData(value.PropertyValue, value.JsonDataType))); } property.Add(new JProperty("properties", metaProperties)); } propertyArray.Add(property); } vertexProperties.Add(new JProperty(propertyName, propertyArray)); } vertex.Add(new JProperty("properties", vertexProperties)); vertexGraphSON.Add(vertex.ToString(Formatting.None)); } this.subgraphState.graph = new StringField("[" + string.Join(", ", vertexGraphSON) + "]"); } else { this.subgraphState.graph = new StringField("[]"); } return(this.subgraphState.graph); }