Пример #1
0
        private string CreateFilterExpression(MediaSearchOptions o)
        {
            var subexpressions = new List <string>();

            if (o.LocationFilter != null && o.LocationFilter.Count > 0)
            {
                subexpressions.Add(string.Join(" or ", o.LocationFilter.Select(location => $"LocationName eq '{location.Replace("'", "''")}'")));
            }

            if (o.TagFilter != null && o.TagFilter.Count > 0)
            {
                subexpressions.Add(string.Join(" or ", o.TagFilter.Select(tag => $"Tag/any(t: t eq '{tag.Replace("'", "''")}')")));
            }

            if (o.MinDateTaken != null)
            {
                string minDateTakenString = DateTimeOffset.FromUnixTimeSeconds(o.MinDateTaken.Value).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
                subexpressions.Add($"DateTaken ge {minDateTakenString}");
            }

            if (o.MaxDateTaken != null)
            {
                string maxDateTakenString = DateTimeOffset.FromUnixTimeSeconds(o.MaxDateTaken.Value).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
                subexpressions.Add($"DateTaken le {maxDateTakenString}");
            }

            if (o.MinDateUploaded != null)
            {
                string minDateUploadedString = DateTimeOffset.FromUnixTimeSeconds(o.MinDateUploaded.Value).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
                subexpressions.Add($"UploadDate ge {minDateUploadedString}");
            }

            if (o.MaxDateUploaded != null)
            {
                string maxDateUploadedString = DateTimeOffset.FromUnixTimeSeconds(o.MaxDateUploaded.Value).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
                subexpressions.Add($"UploadDate le {maxDateUploadedString}");
            }

            string spatialExpression = TransformSpatialFilter(o.SpatialFilter);

            if (spatialExpression != null)
            {
                subexpressions.Add(spatialExpression);
            }

            if (o.DistanceSearch != null)
            {
                var lat = o.DistanceSearch.Point.Latitude;
                var lon = o.DistanceSearch.Point.Longitude;
                subexpressions.Add($"geo.distance(Location, geography'POINT({lon} {lat})') le {o.DistanceSearch.Radius / 1000.0}");
            }

            return(string.Join(" and ", subexpressions));
        }
Пример #2
0
        public async Task <MediaSearchResult> QueryAsync(
            string searchTerm,
            MediaSearchOptions searchOptions,
            int?count = null,
            int?skip  = null)
        {
            searchTerm = searchTerm ?? "";

            string filterExpression;

            try
            {
                filterExpression = CreateFilterExpression(searchOptions);
            }
            catch (ArgumentException ex) // Invalid spatial filter
            {
                return(new MediaSearchResult());
            }

            var parameters = new SearchParameters()
            {
                Filter = filterExpression,

                // Enter media property names into this list, so only these values will be returned.
                Select = new[] { "Id", "Name", "Caption", "FileURL", "ThumbnailURL", "Location", "Author", "LocationName", "Tag", "Project", "UploadDate" },

                // Order newest uploads first.
                OrderBy = new[] { "UploadDate desc" },

                // Skip past results that have already been returned.
                Skip = skip,

                // Take only the next page worth of results.
                Top = count,

                // Include the total number of results.
                IncludeTotalResultCount = true,
            };

            var result = await _searchIndexClient.Documents.SearchAsync <MediaItem>(searchTerm, parameters);

            _logger.LogInformation("Completed search query successfully");

            return(new MediaSearchResult(result));
        }
        public async Task <IActionResult> GetSearch([FromQuery] SearchData model)
        {
            _logger.LogInformation("Search called");

            int page = Math.Max(1, model.Page ?? 1);
            int skip = (page - 1) * GlobalVariables.ResultsPerPage;

            if ((model.Lat != null && model.Lng == null) ||
                (model.Lng != null && model.Lat == null))
            {
                _logger.LogError(
                    "A value for one of Lat or Lng was provided, but the other is missing." + Environment.NewLine +
                    "URL: {url}",
                    HttpContext.Request.GetDisplayUrl());
                return(BadRequest("A value for one of Lat or Lng was provided, but the other is missing"));
            }
            GeographyPoint point = null;

            if (model.Lng != null && model.Lat != null)
            {
                point = GeographyPoint.Create(model.Lat.Value, model.Lng.Value);
            }

            var searchOptions = new MediaSearchOptions()
            {
                LocationFilter = model.LocationFilter,
                TagFilter      = model.TagFilter,
                SpatialFilter  = model.SpatialFilter,
                DistanceSearch = point != null ? new GeoDistanceSearch()
                {
                    Point = point, Radius = 500
                } : null,
                MinDateTaken    = model.MinDateTaken,
                MaxDateTaken    = model.MaxDateTaken,
                MinDateUploaded = model.MinDateUploaded,
                MaxDateUploaded = model.MaxDateUploaded
            };

            var result = await _mediaSearchService.QueryAsync(model.SearchText, searchOptions, GlobalVariables.ResultsPerPage, skip);

            result.TotalPages = ((int)result.Total + GlobalVariables.ResultsPerPage - 1) / GlobalVariables.ResultsPerPage;

            return(Ok(result));
        }