Beispiel #1
0
        private LSHAlgorithm GetPlaneGroup(int groupNumber, int numberOfPlanes, int numberOfDimensions)
        {
            LSHAlgorithm lshAlgorithm;

            var planes = planesCache.Where(p => p.GroupNumber == groupNumber && p.NumberOfDimensions == numberOfDimensions).ToArray();

            if (!planes.Any())
            {
                planes = dbContext.Planes.Where(p => p.GroupNumber == groupNumber && p.NumberOfDimensions == numberOfDimensions).ToArray();
                planesCache.AddRange(planes);
            }

            if (!planes.Any())
            {
                lshAlgorithm = new LSHAlgorithm(numberOfDimensions, numberOfPlanes, -12, 12, 0, 0);
                foreach (var plane in lshAlgorithm.Planes)
                {
                    var newPlane = new Plane
                    {
                        GroupNumber        = groupNumber,
                        NumberOfDimensions = numberOfDimensions,
                        Coordinate1        = TryGetPlaneCoordinate(plane, 0),
                        Coordinate2        = TryGetPlaneCoordinate(plane, 1),
                        Coordinate3        = TryGetPlaneCoordinate(plane, 2),
                        Coordinate4        = TryGetPlaneCoordinate(plane, 3),
                        Coordinate5        = TryGetPlaneCoordinate(plane, 4),
                        Coordinate6        = TryGetPlaneCoordinate(plane, 5),
                        Coordinate7        = TryGetPlaneCoordinate(plane, 6),
                        Coordinate8        = TryGetPlaneCoordinate(plane, 7),
                        Coordinate9        = TryGetPlaneCoordinate(plane, 8),
                        Coordinate10       = TryGetPlaneCoordinate(plane, 9),
                        Coordinate11       = TryGetPlaneCoordinate(plane, 10),
                        Coordinate12       = TryGetPlaneCoordinate(plane, 11),
                        Translation1       = TryGetPlaneTranslation(plane, 0),
                        Translation2       = TryGetPlaneTranslation(plane, 1),
                        Translation3       = TryGetPlaneTranslation(plane, 2),
                        Translation4       = TryGetPlaneTranslation(plane, 3),
                        Translation5       = TryGetPlaneTranslation(plane, 4),
                        Translation6       = TryGetPlaneTranslation(plane, 5),
                        Translation7       = TryGetPlaneTranslation(plane, 6),
                        Translation8       = TryGetPlaneTranslation(plane, 7),
                        Translation9       = TryGetPlaneTranslation(plane, 8),
                        Translation10      = TryGetPlaneTranslation(plane, 9),
                        Translation11      = TryGetPlaneTranslation(plane, 10),
                        Translation12      = TryGetPlaneTranslation(plane, 11)
                    };
                    dbContext.Planes.Add(newPlane);
                    planesCache.Add(newPlane);
                }
                Console.WriteLine($"Planes created for group {groupNumber} in {numberOfDimensions} dimensions.");
                dbContext.SaveChanges();
            }
            else
            {
                lshAlgorithm = new LSHAlgorithm(planes.Select(p => new TranslatedVector(new double[] {
                    p.Coordinate1, p.Coordinate2, p.Coordinate3, p.Coordinate4,
                    p.Coordinate5, p.Coordinate6, p.Coordinate7, p.Coordinate8,
                    p.Coordinate9, p.Coordinate10, p.Coordinate11, p.Coordinate12
                }.Take(numberOfDimensions).ToArray(),
                                                                                        new double[] {
                    p.Translation1, p.Translation2, p.Translation3, p.Translation4,
                    p.Translation5, p.Translation6, p.Translation7, p.Translation8,
                    p.Translation9, p.Translation10, p.Translation11, p.Translation12
                }.Take(numberOfDimensions).ToArray())).ToArray());
            }

            return(lshAlgorithm);
        }
Beispiel #2
0
        public SearchResultsViewModel Search([FromBody] SearchQuery searchQuery)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var intervals          = searchQuery.Intervals.Take(12).ToArray();
            var intervalsForLsh    = searchQuery.Intervals.Take(Constants.MaxNumberOfDimensionsForLsh).ToArray();
            var lshQueryDictionary = new Dictionary <int, long>();

            if (searchQuery.UseSpatialHashes && intervals.Any())
            {
                for (var groupNumber = 1; groupNumber <= hashGroupsToInclude; groupNumber++)
                {
                    var planes       = context.Planes.Where(p => p.GroupNumber == groupNumber && p.NumberOfDimensions == intervalsForLsh.Length).ToArray();
                    var lshAlgorithm = new LSHAlgorithm(planes.Select(p => new TranslatedVector(new double[] {
                        p.Coordinate1, p.Coordinate2, p.Coordinate3, p.Coordinate4,
                        p.Coordinate5, p.Coordinate6, p.Coordinate7, p.Coordinate8,
                        p.Coordinate9, p.Coordinate10, p.Coordinate11, p.Coordinate12
                    }.Take(intervalsForLsh.Length).ToArray(),
                                                                                                new double[] {
                        p.Translation1, p.Translation2, p.Translation3, p.Translation4,
                        p.Translation5, p.Translation6, p.Translation7, p.Translation8,
                        p.Translation9, p.Translation10, p.Translation11, p.Translation12
                    }.Take(intervalsForLsh.Length).ToArray()
                                                                                                )).ToArray());
                    lshQueryDictionary.Add(groupNumber, lshAlgorithm.ComputeHash(new Vector(intervalsForLsh.Select(ii => (double)ii).ToArray())));
                }
            }

            var sb = new StringBuilder();

            sb.AppendLine($"SELECT i.{nameof(Incipit.Id)}, i.{nameof(Incipit.MusicalNotation)}, i.{nameof(Incipit.Clef)}, i.{nameof(Incipit.KeySignature)}, i.{nameof(Incipit.TimeSignature)}, " +
                          $"i.{nameof(Incipit.CaptionOrHeading)}, ms.{nameof(MusicalSource.ComposerName)}, ms.{nameof(MusicalSource.Id)}, i.{nameof(Incipit.TextIncipit)}, " +
                          $"ms.{nameof(MusicalSource.Title)}, i.{nameof(Incipit.VoiceOrInstrument)}, ");
            sb.AppendLine(GetRelevanceExpression(intervals));
            sb.AppendLine(" from incipits i inner join musicalsources ms on ms.id = i.MusicalSourceId ");
            var isWhereBlockStarted = false;

            if (searchQuery.UseSpatialHashes && intervals.Any())
            {
                isWhereBlockStarted = true;
                sb.AppendLine($" WHERE i.Hash{intervalsForLsh.Length}d = {lshQueryDictionary[1]} ");
            }

            var parameters = new List <object>();

            if (!string.IsNullOrWhiteSpace(searchQuery.Rhythm))
            {
                parameters.Add(searchQuery.Rhythm + "%");
                if (searchQuery.IsRhythmRelative)
                {
                    sb.AppendLine($" {(isWhereBlockStarted ? "AND" : "WHERE")} i.RhythmRelativeDigest LIKE @p0 ");
                }
                else
                {
                    sb.AppendLine($" {(isWhereBlockStarted ? "AND" : "WHERE")} i.RhythmDigest LIKE @p0 ");
                }
            }
            if (intervals.Any())
            {
                sb.Append($" order by Relevance desc");
            }
            else
            {
                sb.Append($" order by i.Id asc");
            }

            sb.AppendLine($" LIMIT {searchQuery.Take} OFFSET {searchQuery.Skip}");

            var sql = sb.ToString();

            Debug.WriteLine(sql);
            var incipits = context.RawSqlQuery(sql, parameters.ToArray());
            var results  = incipits.Select(r =>
            {
                var score = plaineAndEasieService.ParseAndColorMatchingIntervals(r[1] as string, r[2] as string, r[3] as string, r[4] as string, intervals);
                return(new SearchResultViewModel
                {
                    Id = r[0].ToString(),
                    IncipitSvg = score == null ? null : scoreRendererService.RenderScore(score),
                    CaptionOrHeading = r[5] as string,
                    ComposerName = r[6] as string,
                    RecordId = r[7] as string,
                    TextIncipit = r[8] as string,
                    Title = r[9] as string,
                    Voice = r[10] as string,
                    Relevance = r[11] is double?(double)r[11] : (long)r[11],
                    ShowRelevance = intervals.Any(),
                    PlaineAndEasieCode = isAdminMode ? $"{r[1]};{r[2]};{r[3]};{r[4]}" : ""
                });
            }).ToArray();

            stopwatch.Stop();

            return(new SearchResultsViewModel {
                Results = results, QueryTime = stopwatch.ElapsedMilliseconds
            });
        }