Skip to content

Commit

Permalink
search impreovements
Browse files Browse the repository at this point in the history
  • Loading branch information
uleus authored and uleus committed Feb 4, 2021
1 parent 02cac77 commit 5e7261b
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class SearchableBaseItem
[Text(Analyzer = "autocomplete", SearchAnalyzer = "autocomplete_search", Name = nameof(Name))]
public string Name { get; set; }

[Keyword(Name = nameof(State))]
[Text(Name = nameof(State))]
public string State { get; set; }

//multifieds : mapping in code
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Nest;

namespace Search.Elasticsearch.Search
namespace Search.Elasticsearch.Searching
{
public interface IElasticClientFactoryService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Search.Elasticsearch.Search
namespace Search.Elasticsearch.Searching
{
public interface ISearchService
{
Expand All @@ -23,45 +23,29 @@ public SearchService(IElasticClientFactoryService aElasticClientFactoryService)

public async Task<SimpleSerachResponse> Search(SimpleSearchRequest aSearchRequest)
{
BoolQuery filterQuery = new BoolQuery();
if (!string.IsNullOrEmpty(aSearchRequest.MarketFilterQuery))
{
//we assume that:
// 1: the MarketFilterQuery is in fromat Market1,Market2,Market3 e.g. Austin, San Paulo
// 2: the market names are coming from predefined table, so no spelling mistakes, no autocompletition
// 3: keyword field, and keyword_list_serach analyzer are created with the index
var filterQueryParts = new List<QueryContainer>();
filterQueryParts.Add(
new MatchQuery()
{
Field = "Market.keyword",
Query = aSearchRequest.MarketFilterQuery,//.ToLower(),
Analyzer = "keyword_list_serach"
}
);

filterQuery.Filter = filterQueryParts;
}
BoolQuery filterQuery = BuildMarketFilterQuery(aSearchRequest.MarketFilterQuery);

//check the API to be able to get the specific SearchableBaseItem derived types (something similar to ConcreteTypeSelector?)
//for now we use JsonObject and convert it to specific object base on the "TypeName"

var results = await _client.SearchAsync<JsonObject>(s => s
.Size(aSearchRequest.PageSize)
.Skip(aSearchRequest.PageStartIndex)
.Index(Indices.Index(aSearchRequest.Indices))
.Index(Indices.Index(aSearchRequest.Indices))
.Query(q => q
.Bool(b => b
.Should(
// for City and Market a 'phrase' field is crated, which allowes
// to better place the item in result when the city/market was put in the AllStringFiledsQuery
// for City and Market a 'phrase' field is created, which allowes
// to better place the item in result when the city/market was put as the AllStringFiledsQuery
// e.g. if someone put the AllStringFiledsQuery="San Francisco" ...
// but this match will not work in case of putting the AllStringFiledsQuery="San Francisco properties"
bs => bs.MatchPhrase(x => x
.Query(aSearchRequest.AllStringFiledsQuery.ToLower())
.Field("City.phrase")
),
bs => bs.MatchPhrase(x => x
.Query(aSearchRequest.AllStringFiledsQuery.ToLower())
.Field("Market.phrase")
.Field("Market.phrase")
)
)
.Must(
Expand All @@ -79,28 +63,49 @@ public async Task<SimpleSerachResponse> Search(SimpleSearchRequest aSearchReques
.Field($"{nameof(SearchablePropertyItem.FormerName)}")
.Field($"{nameof(SearchablePropertyItem.StreetAddres)}")
.Field($"{nameof(SearchablePropertyItem.City)}")
)
)
.Fuzziness(Fuzziness.Auto)
),
bs => filterQuery
)
)
)
)
);



return new SimpleSerachResponse()
{
TotalItems = results.Total,
Items = ConvertResults(results)
};
}

//we assume that:
// 1: the MarketFilterQuery is in fromat Market1,Market2,Market3 e.g. Austin, San Paulo
// 2: the market names are coming from predefined table, so no spelling mistakes, no autocompletition
// 3: keyword field, and keyword_list_serach analyzer are created with the index
private BoolQuery BuildMarketFilterQuery(string aMarket)
{
BoolQuery filterQuery = new BoolQuery();
if (!string.IsNullOrEmpty(aMarket))
{
var filterQueryParts = new List<QueryContainer>();
filterQueryParts.Add(
new MatchQuery()
{
Field = "Market.keyword",
Query = aMarket,
Analyzer = "keyword_list_serach"
}
);

filterQuery.Filter = filterQueryParts;
}

return filterQuery;
}

private List<SearchableBaseItem> ConvertResults(ISearchResponse<JsonObject> aSerachResponse)
{

{
List<SearchableBaseItem> ret = new List<SearchableBaseItem>();

foreach (var item in aSerachResponse.Documents)
Expand All @@ -111,21 +116,21 @@ private List<SearchableBaseItem> ConvertResults(ISearchResponse<JsonObject> aSer
ret.Add(new SearchableManagementItem()
{
Id = int.Parse(item["Id"].ToString()),
Name = (string)item["Name"],
State = (string)item["State"],
Market = (string)item["Market"]
Name = item.ContainsKey("Name") ? item["Name"].ToString() : "not exist",
State = item.ContainsKey("State") ? item["State"].ToString() : "not exist",
Market = item.ContainsKey("Market") ? item["Market"].ToString() : "not exist",
});
break;
case "searchablepropertyitem":
ret.Add(new SearchablePropertyItem()
{
Id = int.Parse(item["Id"].ToString()),
Name = item["Name"].ToString(),
State = item["State"].ToString(),
Market = item["Market"].ToString(),
FormerName = item.ContainsKey("FormerName") ? item["FormerName"].ToString() : "",
StreetAddres = item["StreetAddres"].ToString(),
City = (string)item["City"].ToString(),
Name = item.ContainsKey("Name") ? item["Name"].ToString(): "not exist",
State = item.ContainsKey("State") ? item["State"].ToString(): "not exist",
Market = item.ContainsKey("Market") ? item["Market"].ToString(): "not exist",
FormerName = item.ContainsKey("FormerName") ? item["FormerName"].ToString() : "not exist",
StreetAddres = item.ContainsKey("StreetAddres") ? item["StreetAddres"].ToString() : "not exist",
City = item.ContainsKey("City") ? (string)item["City"].ToString() : "not exist",
//Lat = (float) item["lat"],
//Lng = (float) item["lng"]
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System.Collections.Generic;

namespace Search.Elasticsearch.Search
namespace Search.Elasticsearch.Searching
{

public class SimpleSearchRequest
{
public List<string> Indices { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using Search.Elasticsearch.Mapping;
using System;
using System.Collections.Generic;
using System.Text;

namespace Search.Elasticsearch.Search
namespace Search.Elasticsearch.Searching
{
public class SimpleSerachResponse
{
Expand Down
6 changes: 3 additions & 3 deletions Elasticsearch/Search.IndexData.Exe/DataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ public DataProvider()
Market="Austin",
State ="GS",
StreetAddres = "3549 Curry Lane",
City = "San Francesco"
City = "San Francisco"
},
new SearchablePropertyItem()
{
Id = 2,
Name ="Forest at Columbia AAAA San in Paulo",
StreetAddres = "1000 Merrick Ferry Road San in Paulo",
Name ="Forest at Columbia AAAA San in Paulo San Francisco",
StreetAddres = "1000 Merrick Ferry Road San Francisco",
Market="Austin",
State ="GS",
City = "San in Paulo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Microsoft.Extensions.Logging;
using Search.Elasticsearch;
using Search.Elasticsearch.Mapping;
using Search.Elasticsearch.Search;
using Search.Elasticsearch.Searching;
using Search.WebAPI.Exe.Dto;

namespace Search.WebAPI.Exe.Controllers
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Configuration;
using Nest;
using Search.Elasticsearch.Search;
using Search.Elasticsearch.Searching;
using System;

namespace Search.WebAPI.Exe.Services
Expand Down
8 changes: 1 addition & 7 deletions Elasticsearch/Search.WebAPI.Exe/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Search.Elasticsearch.Search;
using Search.Elasticsearch.Searching;
using Search.WebAPI.Exe.Services;

namespace Search.WebAPI.Exe
Expand Down

0 comments on commit 5e7261b

Please sign in to comment.