Example #1
0
        /// <summary>
        /// Return establishment list.
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public ListResult <EstablishmentListDTO> List(EstablishmentFilter filter)
        {
            IAggregateFluent <Establishment> establishmentAggregateFluent = this.MongoRepository
                                                                            .GetCollection <Establishment>().Aggregate();

            if (filter.GeospatialQuery)
            {
                if (!filter.Meters.HasValue)
                {
                    filter.Meters = 10000;
                }

                BsonDocument geoNearOptions = new BsonDocument {
                    {
                        "near", new BsonDocument {
                            { "type", "Point" },
                            { "coordinates", new BsonArray {
                                  filter.Longitude.Value, filter.Latitude.Value
                              } },
                        }
                    },
                    { "maxDistance", filter.Meters },
                    { "includeLocs", "Location.Coordinates" },
                    { "distanceField", "Location.Distance" },
                    { "spherical", true }
                };

                establishmentAggregateFluent = establishmentAggregateFluent.AppendStage(
                    (PipelineStageDefinition <Establishment, Establishment>) new BsonDocument {
                    { "$geoNear", geoNearOptions }
                }
                    );

                this.TelemetryClient.TrackEvent(
                    EventNames.EstablishmentListLocation,
                    new { filter.Latitude, filter.Longitude }
                    );
            }

            if (filter.EstablishmentType.HasValue)
            {
                establishmentAggregateFluent = establishmentAggregateFluent
                                               .Match(document => document.EstablishmentTypes.Contains(filter.EstablishmentType.Value));

                this.TelemetryClient.TrackEvent(
                    EventNames.EstablishmentListType,
                    new { filter.EstablishmentType }
                    );
            }

            if (!string.IsNullOrEmpty(filter.Query))
            {
                establishmentAggregateFluent = establishmentAggregateFluent.Match(
                    document => document.Name.Contains(filter.Query) ||
                    document.Description.Contains(filter.Query)
                    );

                this.TelemetryClient.TrackEvent(
                    EventNames.EstablishmentListQuery,
                    new { filter.Query }
                    );
            }

            if (filter.DaysOfWeekEnum != null)
            {
                Expression <Func <Establishment, bool> > availabilityExpression = document => false;

                foreach (DayOfWeekEnum dayOfWeek in filter.DaysOfWeekEnum)
                {
                    availabilityExpression = availabilityExpression.Or(
                        document => document.Availabilities.Any(
                            availability => availability.DayOfWeek == dayOfWeek || availability.CloseDayOfWeek == dayOfWeek
                            )
                        );
                }

                establishmentAggregateFluent = establishmentAggregateFluent.Match(availabilityExpression);

                this.TelemetryClient.TrackEvent(
                    EventNames.EstablishmentListDaysOfWeek,
                    new { filter.DaysOfWeek }
                    );
            }

            IAggregateFluent <BsonDocument> aggregateFluent = establishmentAggregateFluent.As <BsonDocument>();

            aggregateFluent = filter.OrderType == OrderTypeEnum.Distance
                ? aggregateFluent.SortBy(document => document["Location"]["Distance"])
                : aggregateFluent.SortByDescending(document => document["Relevance"]);

            if (!this.UserContext.EstablishmentId.HasValue)
            {
                this.RelevanceService.Register <Establishment, EstablishmentFilter>(filter);
            }

            IEnumerable <BsonDocument> documents = aggregateFluent
                                                   .Skip((filter.Page - 1) * filter.PageSize)
                                                   .Limit(filter.PageSize)
                                                   .ToList();

            IEnumerable <EstablishmentListDTO> establishments = documents.Select(document =>
                                                                                 new EstablishmentListDTO
            {
                Id = document["_id"].AsObjectId,
                EstablishmentTypes = document["EstablishmentTypes"].AsBsonArray.Select(x => (EstablishmentTypeEnum)x.AsInt32),
                ImageThumbnail     = document["ImageThumbnail"]["Uri"].AsString,
                Name     = document["Name"].AsString,
                Distance = document["Location"].AsBsonDocument.Contains("Distance")
                        ? document["Location"]["Distance"].AsDouble
                        : (double?)null
            }
                                                                                 ).ToList();

            return(new ListResult <EstablishmentListDTO>(
                       establishments,
                       aggregateFluent.Count().FirstOrDefault()?.Count ?? 0,
                       filter
                       ));
        }