Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
 public override void Authorize(DuplicatesQuery query)
 {
     Auth.AssertPermission(Resources.AdminDuplicates, query.NetworkId);
 }