Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added logic of geo search workshops to db services #418

Merged
merged 8 commits into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions OutOfSchool/OutOfSchool.Common/GeoMathHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;

namespace OutOfSchool.Common
{
public static class GeoMathHelper
{
public static decimal GetDistanceFromLatLonInKm(double lat1, double lon1, double lat2, double lon2)
{
var r = 6371e3; // Radius of the earth in m
var dLat = Deg2rad(lat2 - lat1); // Deg2rad below
var dLon = Deg2rad(lon2 - lon1);
var a =
(Math.Sin(dLat / 2) * Math.Sin(dLat / 2)) +
(Math.Cos(Deg2rad(lat1)) * Math.Cos(Deg2rad(lat2)) *
Math.Sin(dLon / 2) * Math.Sin(dLon / 2));
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var d = r * c; // Distance in km
return (decimal)d;
}

public static double Deg2rad(double deg)
{
return deg * (Math.PI / 180);
}
}
}
4 changes: 4 additions & 0 deletions OutOfSchool/OutOfSchool.DataAccess/Models/Address.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel.DataAnnotations;
using H3Lib;

namespace OutOfSchool.Services.Models
{
Expand Down Expand Up @@ -30,6 +31,9 @@ public class Address

public double Longitude { get; set; }

// parameter r means size (resolution) of hexagon
public ulong GeoHash => H3Lib.Api.GeoToH3(new GeoCoord((decimal)Latitude, (decimal)Longitude), 6);

public override bool Equals(object obj)
{
if (obj == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="H3Lib" Version="3.7.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
Expand Down
68 changes: 57 additions & 11 deletions OutOfSchool/OutOfSchool.ElasticsearchData/ESWorkshopProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace OutOfSchool.ElasticsearchData
{
/// <inheritdoc/>
public class ESWorkshopProvider : ElasticsearchProvider<WorkshopES, WorkshopFilterES>, IElasticsearchProvider<WorkshopES, WorkshopFilterES>
public class ESWorkshopProvider : ElasticsearchProvider<WorkshopES, WorkshopFilterES>,
IElasticsearchProvider<WorkshopES, WorkshopFilterES>
{
public ESWorkshopProvider(ElasticClient elasticClient)
: base(elasticClient)
Expand All @@ -26,14 +27,16 @@ public override async Task<SearchResultES<WorkshopES>> Search(WorkshopFilterES f

var query = this.CreateQueryFromFilter(filter);
var sorts = this.CreateSortFromFilter(filter);

var resp = await ElasticClient.SearchAsync<WorkshopES>(new SearchRequest<WorkshopES>()
var req = new SearchRequest<WorkshopES>()
{
Query = query,
Sort = sorts,
From = filter.From,
Size = filter.Size,
});

};

var resp = await ElasticClient.SearchAsync<WorkshopES>(req);

return new SearchResultES<WorkshopES>() { TotalAmount = (int)resp.Total, Entities = resp.Documents };
}
Expand Down Expand Up @@ -164,6 +167,20 @@ private QueryContainer CreateQueryFromFilter(WorkshopFilterES filter)
},
};
}

if (Equals(OrderBy.Nearest.ToString(), filter.OrderByField))
{
queryContainer &= new GeoDistanceQuery()
{
Boost = 1.1,
Name = "named_query",
Field = Infer.Field<WorkshopES>(w => w.Address.Point),
DistanceType = GeoDistanceType.Arc,
Location = new GeoLocation((double)filter.Latitude, (double)filter.Longitude),
Distance = "5000m",
ValidationMethod = GeoValidationMethod.IgnoreMalformed,
};
}

if (filter.MinStartTime.TotalMinutes > 0 || filter.MaxStartTime.Hours < 23)
{
Expand Down Expand Up @@ -198,31 +215,60 @@ private List<ISort> CreateSortFromFilter(WorkshopFilterES filter)
switch (filter.OrderByField)
{
case nameof(OrderBy.Rating):
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Rating), Order = SortOrder.Descending });
sorts.Add(new FieldSort()
{
Field = Infer.Field<WorkshopES>(w => w.Rating),
Order = SortOrder.Descending,
});
break;

case nameof(OrderBy.Statistic):
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Rating), Order = SortOrder.Descending });
sorts.Add(new FieldSort()
{
Field = Infer.Field<WorkshopES>(w => w.Rating),
Order = SortOrder.Descending,
});
break;

case nameof(OrderBy.PriceAsc):
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Price), Order = SortOrder.Ascending });
sorts.Add(new FieldSort()
{
Field = Infer.Field<WorkshopES>(w => w.Price),
Order = SortOrder.Ascending,
});
break;

case nameof(OrderBy.PriceDesc):
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Price), Order = SortOrder.Descending });
sorts.Add(new FieldSort()
{
Field = Infer.Field<WorkshopES>(w => w.Price),
Order = SortOrder.Descending,
});
break;

case nameof(OrderBy.Alphabet):
sorts.Add(new FieldSort() { Field = "title.keyword", Order = SortOrder.Ascending });
sorts.Add(new FieldSort()
{
Field = "title.keyword",
Order = SortOrder.Ascending,
});
break;

case nameof(OrderBy.Nearest):
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Rating), Order = SortOrder.Descending });
sorts.Add(new GeoDistanceSort()
{
Field = Infer.Field<WorkshopES>(w => w.Address.Point),
Points = new[] { new GeoLocation((double)filter.Latitude, (double)filter.Longitude) },
Order = SortOrder.Ascending,
});
break;

default:
sorts.Add(new FieldSort() { Field = Infer.Field<WorkshopES>(w => w.Id), Order = SortOrder.Ascending });
sorts.Add(new FieldSort()
{
Field = Infer.Field<WorkshopES>(w => w.Id),
Order = SortOrder.Ascending,
});
break;
}

Expand Down
8 changes: 5 additions & 3 deletions OutOfSchool/OutOfSchool.ElasticsearchData/Models/AddressES.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace OutOfSchool.ElasticsearchData.Models
using Nest;

namespace OutOfSchool.ElasticsearchData.Models
{
public class AddressES
{
Expand All @@ -14,8 +16,8 @@ public class AddressES

public string BuildingNumber { get; set; }

public double Latitude { get; set; }
[GeoPoint]
public GeoLocation Point { get; set; }

public double Longitude { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,9 @@ public class WorkshopFilterES
public int Size { get; set; } = 12;

public int From { get; set; } = 0;

public decimal Latitude { get; set; } = 0;

public decimal Longitude { get; set; } = 0;
}
}
Loading