[CSHARP-3097] How to cleanly deal with full text search and sort by score when search term is an empty string? Created: 08/May/20  Updated: 18/May/20  Resolved: 18/May/20

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major - P3
Reporter: Michael Fyffe Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello,

 

We are implementing full text search in our application and ran into a couple of situations that seemed less than ideal. Mainly when dealing with the possibility of the user entering in an empty string for the search string and trying to sort by score.

 

  1. Aggregation pipeline is unable to be built dynamically

I was hoping i could do something like this to dynamically compose the pipeline.

 

 

var query = GetCollection<TDocument>()
.Aggregate()
.Match(filter)
.Skip(criteria.Skip)
.Limit(criteria.Take);
 
if (!String.IsNullOrWhiteSpace(criteria.SearchString))
{
                results = query
.Sort(Builders<TDocument>.Sort.MetaTextScore("Score"));
}
 
query.Project(new {
// stuff here
}).ToList();

What i noticed is that the sort filter was not getting added as a pipeline stage.

 

 

2. There is no concept of an Empty Sort Definition like Filters so i couldn't sort by score which is ideal

 

 

var filterDefinition = Builders<TDocument>.Filter.Empty
if (!String.IsNullOrWhiteSpace(searchCriteria.SearchString))
{                filterDefinition &= Builders<MediaDocument>.Filter.Text(searchCriteria.SearchString);            }
 
var sortDefinition = Builders<TDocument>.Sort.Empty // <-- this doesn't exist like filters
 
if (!String.IsNullOrWhiteSpace(criteria.SearchString))
{
   sortDefinition &= Builders<TDocument>.Sort.MetaTextScore("Score")
}
 
var query = GetCollection<TDocument>()
.Aggregate()
.Match(filterDefinition)
.Skip(criteria.Skip)
.Limit(criteria.Take)
.Sort(sortDefinition)
query.Project(new { // stuff here }).ToList();;

 

 

In the end i pretty much ended up doing this.  It works and does make sense but at the downside of duplicating parts of the query.

 

 

 if (!String.IsNullOrWhiteSpace(criteria.SearchString))
            {
                results = GetCollection<TDocument>()
                    .Aggregate()
                    .Match(filter)
                    .Skip(criteria.Skip)
                    .Limit(criteria.Take)
                    .Sort(Builders<TDocument>.Sort.MetaTextScore("Score"))
                    .ToList();
            }
            else
            {
                results = GetCollection<TDocument>()
                    .Aggregate()
                    .Match(filter)
                    .Skip(criteria.Skip)
                    .Limit(criteria.Take)
                    .ToList();
            }

 

 

I would love some feedback if there is a cleaner alternative way of doing the above.

 

Thanks!

 



 Comments   
Comment by Esha Bhargava [ 18/May/20 ]

Thanks for your report. Please note that this project is for reporting bugs or feature suggestions for the driver. For MongoDB-related support discussion please post on the MongoDB Community Forums. A question like this involving more discussion would be best posted on the MongoDB community.

Generated at Wed Feb 07 21:44:21 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.