Exemple #1
0
        internal static void AssertGraphsEqual(PropertyGraphModel expected, PropertyGraphModel actual)
        {
            var left  = (JObject)JsonConvert.DeserializeObject(JsonConvention.SerializeObject(SortGraph(expected)));
            var right = (JObject)JsonConvert.DeserializeObject(JsonConvention.SerializeObject(SortGraph(actual)));

            Sort(left); Sort(right);
            Assert.AreEqual(left.ToString(Formatting.None), right.ToString(Formatting.None));
            //Assert.AreEqual(JsonConvention.SerializeObject(SortGraph(expected)), JsonConvention.SerializeObject(SortGraph(actual)));
        }
        public async override Task Execute(SaveVertexCommand cmd)
        {
            var vertexProps = await UnitOfWork.Db.VertexProperties.Where(
                p => p.VertexId == cmd.VertexId && p.Deleted == null).ToListAsync();

            foreach (var propModel in cmd.Props)
            {
                // close old value if present
                var prop = vertexProps.FirstOrDefault(p => p.SchemaUri == propModel.SchemaUri);

                // serialize value to json
                var jsonValue = JsonConvention.SerializeObject(propModel.Value);

                if (prop != null)
                {
                    if (prop.JsonValue == jsonValue)
                    {
                        // nothing to update
                        continue;
                    }
                    else
                    {
                        // different value - close old property and continue
                        prop.Deleted = _clock.TimeStamp;
                    }
                }

                // if value is null do not add anything
                if (propModel.Value == null)
                {
                    continue;
                }

                // create property
                var newProp = new VertexProperty()
                {
                    Id        = Guid.NewGuid(),
                    VertexId  = cmd.VertexId,
                    SchemaUri = propModel.SchemaUri,
                    Created   = _clock.TimeStamp,
                    JsonValue = jsonValue
                };
                UnitOfWork.Db.VertexProperties.Add(newProp);

                // prevent inserting duplicates
                vertexProps.Add(newProp);
            }

            await Events.OnNext(new SaveVertexCompletedEvent()
            {
                Command = cmd
            });
        }
        /// <summary>
        /// Assumes layout has been already applied
        /// Note: method mutates graph and graphLayout
        /// </summary>
        public void ImproveAppliedLayout(SigmaGraphModel graph, GraphLayout graphLayout, LayoutSettings layoutSettings, TimeSpan duration)
        {
            using (var engine = new V8ScriptEngine())
            {
                try
                {
                    var v8Graph = new V8GraphModel();
                    v8Graph.LoadSigma(graph);
                    engine.AddHostObject("log", _log);

                    engine.Execute("var graph = " + JsonConvention.SerializeObject(v8Graph) + ";");
                    engine.Execute("var settings = " + JsonConvention.SerializeObject(layoutSettings) + ";");
                    engine.Execute("var duration = " + JsonConvention.SerializeObject(duration.TotalMilliseconds) + ";");

                    var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;

                    var forceAtlas2   = engine.Compile(File.ReadAllText($@"{baseDirectory}\App\Graph\Layout\ForceAtlas2.js"));
                    var serviceScript = engine.Compile(File.ReadAllText($@"{baseDirectory}\App\Graph\Layout\GraphLayoutService.js"));
                    engine.Execute(forceAtlas2);
                    engine.Execute(serviceScript);

                    var nodesJson = engine.Evaluate("JSON.stringify(nodes)").ToString();
                    var nodes     = JsonConvention.DeserializeObject <V8NodeModel[]>(nodesJson);
                    for (int i = 0; i < nodes.Length; i++)
                    {
                        var node = graph.Nodes[i];
                        node.X = nodes[i].x;
                        node.Y = nodes[i].y;

                        var id = node.Entity;
                        if (id.HasValue)
                        {
                            graphLayout[id.Value] = new GraphLayout.Coords()
                            {
                                X = nodes[i].x,
                                Y = nodes[i].y
                            };
                        }
                    }
                }
                catch (ScriptEngineException e)
                {
                    _log.Error("V8 exception: " + e.ErrorDetails);
                    throw;
                }
            }
        }
        public async override Task Execute(CreateVertexCommand cmd)
        {
            UnitOfWork.Db.Vertices.Add(new Vertex()
            {
                Id        = cmd.VertexId,
                NetworkId = cmd.NetworkId,
                Created   = _clock.TimeStamp
            });

            if (cmd.Props != null)
            {
                foreach (var propModel in cmd.Props)
                {
                    // serialize value to json
                    var jsonValue = JsonConvention.SerializeObject(propModel.Value);

                    // if value is null do not add anything
                    if (propModel.Value == null)
                    {
                        continue;
                    }

                    // create property
                    var newProp = new VertexProperty()
                    {
                        Id        = Guid.NewGuid(),
                        VertexId  = cmd.VertexId,
                        SchemaUri = propModel.SchemaUri,
                        Created   = _clock.TimeStamp,
                        JsonValue = jsonValue
                    };
                    UnitOfWork.Db.VertexProperties.Add(newProp);
                }
            }

            await Events.OnNext(new SaveVertexCompletedEvent()
            {
                Command = new SaveVertexCommand()
                {
                    VertexId = cmd.VertexId,
                    Props    = cmd.Props
                }
            });
        }
Exemple #5
0
        public async override Task Execute(SaveEdgeCommand cmd)
        {
            // is the relationship already there?
            var edge = await UnitOfWork.Db.Edges.Where(
                e => e.SourceVertexId == cmd.SourceVertexId && e.TargetVertexId == cmd.TargetVertexId &&
                e.SchemaUri == cmd.SchemaUri &&
                e.Deleted == null).FirstOrDefaultAsync();

            var edgeExists = (edge != null);

            if (!edgeExists)
            {
                // relationship not found - create edge
                edge = new Entities.Edge()
                {
                    Id             = Guid.NewGuid(),
                    SourceVertexId = cmd.SourceVertexId,
                    TargetVertexId = cmd.TargetVertexId,
                    SchemaUri      = cmd.SchemaUri,
                    Created        = _clock.TimeStamp,
                };
                UnitOfWork.Db.Edges.Add(edge);
            }

            if (cmd.Props != null)
            {
                var edgeProps = await UnitOfWork.Db.EdgeProperties.Where(
                    p => p.EdgeId == edge.Id && p.Deleted == null)
                                .ToListAsync();

                foreach (var propModel in cmd.Props)
                {
                    var jsonValue = JsonConvention.SerializeObject(propModel.Value);

                    if (edgeExists)
                    {
                        // relationship found - find if the proeprty isn't already there
                        var prop = edgeProps.SingleOrDefault(p => p.SchemaUri == propModel.SchemaUri);

                        if (prop != null)
                        {
                            if (prop.JsonValue == jsonValue)
                            {
                                // nothing to update
                                continue;
                            }
                            else
                            {
                                // different value - close old property and continue
                                prop.Deleted = _clock.TimeStamp;
                            }
                        }
                    }

                    // if value is null do not add anything
                    if (propModel.Value == null)
                    {
                        continue;
                    }

                    // create property
                    var newProp = new EdgeProperty()
                    {
                        Id        = Guid.NewGuid(),
                        EdgeId    = edge.Id,
                        SchemaUri = propModel.SchemaUri,
                        Created   = _clock.TimeStamp,
                        JsonValue = jsonValue
                    };
                    UnitOfWork.Db.EdgeProperties.Add(newProp);

                    // prevent inserting duplicate props
                    edgeProps.Add(newProp);
                }
            }

            await Events.OnNext(new SaveEdgeCompletedEvent()
            {
                Command = cmd
            });
        }
Exemple #6
0
        public override async Task <List <DuplicateResult> > Execute(DuplicatesQuery query)
        {
            var graph = (await _queryService.Execute(new InternalGraphQuery()
            {
                NetworkId = query.NetworkId
            }, this))
                        .Snapshot();
            var settings = await _queryService.Execute(new NetworkSettingsQuery()
            {
                NetworkId = query.NetworkId
            }, this);

            var requiredProps = settings.Invitations.RequiredProps;

            var duplicatesByRequiredProps =
                graph.Vertices.Select(
                    v => new {
                Key    = string.Join("::", requiredProps.Select(prop => v.Props.ContainsKey(prop) ? JsonConvention.SerializeObject(v.Props[prop]) : "")),
                Vertex = v
            })
                .GroupBy(g => g.Key)
                .Where(g => g.Count(v => true) > 1)
                .Select(g => new Duplicate()
            {
                Score    = 1,
                Key      = g.Select(a => a.Vertex.Id).OrderBy(id => id).ToArray(),
                Vertices = g.Select(a => a.Vertex)
            });

            var labelProp = settings.ProfileCard.LabelProp;

            var duplicatesByLabel =
                graph.Vertices.Select(
                    v => new {
                Label  = v.Props.ContainsKey(labelProp) ? v.Props[labelProp].ToString().ToLowerInvariant().Trim() : "",
                Vertex = v
            })
                .GroupBy(g => g.Label)
                .Where(g => g.Count(v => true) > 1)
                .Select(g => new Duplicate()
            {
                Score    = 0.5,
                Key      = g.Select(a => a.Vertex.Id).OrderBy(id => id).ToArray(),
                Vertices = g.Select(a => a.Vertex)
            });

            var duplicates = duplicatesByRequiredProps.ToDictionary(d => d.Key, d => d, new ArrayEqualityComparer());

            foreach (var duplicate in duplicatesByLabel)
            {
                if (!duplicates.ContainsKey(duplicate.Key))
                {
                    duplicates[duplicate.Key] = duplicate;
                }
            }

            var accounts = await
                               (from account in _repo.Db.Accounts
                               join user in _repo.Db.Users on account.ApplicationUserId equals user.Id
                               join vertex in _repo.Db.Vertices on account.VertexId equals vertex.Id
                               where vertex.NetworkId == query.NetworkId
                               group new { user.Email, account.InvitationDate } by vertex.Id into g
                               select new
            {
                VertexId = g.Key,
                Accounts = g.ToList()
            }
                               ).ToDictionaryAsync(g => g.VertexId, g => g.Accounts.OrderBy(a => a.InvitationDate));

            var result = new List <DuplicateResult>();

            foreach (var duplicate in duplicates.Values.OrderByDescending(d => d.Score))
            {
                foreach (var vertex in duplicate.Vertices)
                {
                    vertex.Props = vertex.Props.ToProfileCardProps(settings.ProfileCard);
                    if (accounts.ContainsKey(vertex.Id))
                    {
                        vertex.Props["Account email"] = accounts[vertex.Id].First().Email;
                    }
                }
                var firstAccountVertex = duplicate.Vertices.Select(v => new
                {
                    Vertex         = v,
                    InvitationDate =
                        accounts.ContainsKey(v.Id) ? accounts[v.Id].First().InvitationDate : DateTime.MaxValue
                }).OrderBy(a => a.InvitationDate).First();
                result.Add(new DuplicateResult()
                {
                    Vertex     = firstAccountVertex.Vertex,
                    Duplicates = duplicate.Vertices.Where(v => v != firstAccountVertex.Vertex).ToList()
                });
            }

            return(result);
        }