Elastic search NEST - filtered List sorting group wise


(Chenigaram Shweta Reddy) #1

I am new to the elastic search, I have done a bit of research but I could not find the right answer which fits to my requirement. The below query return the results of searched term and surrounding suburbs results together with the filter condition and I want to sort them individually, term search should always be on the top and surrounding suburbs at the bottom, I have done the aggregation so I know the count of search term results.
With the query I am getting something like, if search with the term : Kotara (which is a suburb), I get the result for that suburb and also surrounding suburbs with in the range of 5km. propertyId:1, address.suburb: "charlestown", price:500,000 (1 record which is surrounding suburb) propertyId:2, address.suburb: "kotara", price:500,000 (2nd record, searched term) PropertyId:14, address.suburb:"Newcastle", price:400,000(3rd record, surrounding), propertyId: 4, address.suburb: "kotara", price:200,000 (4th record, searched term)

But I want the result like propertyId:2, address.suburb: "kotara", price:500,000 (1st record, searched term) propertyId: 4, address.suburb: "kotara", price:200,000 (2nd record, searched term)
propertyId:1, address.suburb: "charlestown", price:500,000 (3rd record which is surrounding suburb) PropertyId:14, address.suburb:"Newcastle", price:400,000(3rd record, surrounding)

All the "searched term" results should be at the top of the sorting then all the other sorting conditions should come

FilterContainer termFilters = new FilterContainer();
FilterContainer refineFilters = new FilterContainer();
FilterContainer surroundingFilters = new FilterContainer();
var exactMatches = await _elasticClient.SearchAsync(s => s
.From(requestedPage * request.PageSize)
.Size(request.PageSize > 0 ? request.PageSize : 20)
.Filter(f =>
{
refineFilters = f.Term(t => t.Status, "current");
FilterContainer filter = new FilterContainer();
if (request.Terms != null && request.Terms.Any())
{
foreach (var term in request.Terms)
{
FilterContainer termFilter = new FilterContainer();
termFilter = f.Term(x => x.Address.Suburb, term.Term.ToLower());                           
                 
                     termFilters |=
                         (termFilter
                               && (f.Term(x => x.Address.StateAbbr, term.State.ToLower())
                               || f.Term(x => x.Address.State, term.State.ToLower())));

                     if (request.SurroundingSuburbs)
                     {
                         surroundingFilters |= (f.GeoDistance(g => g.Address.Location, geoDistanceFilterDescriptor => geoDistanceFilterDescriptor
                                                                                                                        .Location(term.Location.Latitude, term.Location.Longitude)
                                                                                                                        .Distance("5km")
                                                                                                                        .DistanceType(GeoDistance.Arc)));
                     }
                                        
             }

             filter = filter && (termFilters || surroundingFilters);
         }

         if (request.ExcludeUnderOffer)
         {
             refineFilters &= f.Term(x => x.UnderOffer, false);
         }
         filter = filter && (refineFilters);
         return filter;
     })              
      .Aggregations(ag =>
      {
         return ag.Filter("SearchTermMatchCount", st => st
                 .Filter(
                     f =>
                     {
                         return termFilters && refineFilters;
                     }).Aggregations(sag => 
                     {
                         return sag.Terms("SearchTermMatch", t => t.Field(sf => sf.Address.Suburb).OrderAscending("_term"));
                         } ));



      })
     .SortGeoDistance(sgd =>
     {
         if (request.Sort == Csn.Dto.Homesales.Enums.SortOrder.Distance)
         {
             return sgd.OnField(x => x.Address.Location)
                                         .Order(Nest.SortOrder.Ascending)
                                         .Unit(GeoUnit.Kilometers)
                                         .Mode(SortMode.Min)
                                         .DistanceType(GeoDistance.Plane)
                                         .PinTo(firstTermLatForSort, firstTermLngForSort);
         }
         else
         {
             return null;
         }
     })

     .Sort(st => 
     {
         switch (request.Sort)
         {
             case Csn.Dto.Homesales.Enums.SortOrder.LatestListing:
                 return st.OnField(x => x.DateCreated).Descending();
             case Csn.Dto.Homesales.Enums.SortOrder.OldestListing:
                 return st.OnField(x => x.DateCreated).Ascending();
             case Csn.Dto.Homesales.Enums.SortOrder.PriceHighest:
                 return st.OnField(x => x.Price.Price).Descending();
             case Csn.Dto.Homesales.Enums.SortOrder.PriceLowest:
                 return st.OnField(x => x.Price.Price).Ascending();
             default:
                 {
                     if (request.Sort != Csn.Dto.Homesales.Enums.SortOrder.Distance)
                     {
                         return st.OnField(x => x.AdPriority).Descending();
                     }
                     else
                     {
                         return null;
                     }
                 }
         }
     }
     )
     );

 response.Matches = exactMatches.Documents.ToList();
 response.Count = exactMatches.Total;

 var aggregation = (SingleBucket)exactMatches.Aggregations.Where(a=>a.Key == "SearchTermMatchCount").Select(a => a.Value);
 response.SearchTermMatchCount = aggregation.DocCount;

(Russ Cam) #2

Please format your code using the </> button, or surround the block in triple back-ticks ```. Take a look at the About Elasticsearch post for more details.

Properly formatted code will help anyone wishing to help more easily read your question, and help you likely get an answer. Thanks!


(system) #3

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.