Details
-
New Feature
-
Resolution: Done
-
Major - P3
-
None
-
None
-
None
-
None
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.
- 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!