To full text search an IMongoQueryable<T>
we can use the following extension method.
public static IMongoQueryable<T> WhereText<T>(this IMongoQueryable<T> query, string search) where T: IScored
{
var filter = Builders<T>.Filter.Text(search);
return query.Where(_ => filter.Inject())
}
Similarly, how can the full text search score, which is normally sorted on using :
private static readonly ProjectionDefinition<ProductTypeSearchResult> TextMatchScoreProjection =
Builders<ProductTypeSearchResult>.Projection.MetaTextScore("Score");
private static readonly SortDefinition<ProductTypeSearchResult> Sort =
Builders<ProductTypeSearchResult>.Sort.MetaTextScore("score");
collection.Find(...).Project(TextMatchScoreProjection).Sort(Sort);
be implemented using IMongoQueryable<T>
The examples are blank in the documentation https://mongodb.github.io/mongo-csharp-driver/2.8/reference/driver/expressions/#text
Given a class member:
private readonly IMongoCollection<SomeType> _someTypes;
The code to inject the query score will look like:
private IAggregateFluent<SomeType> CreateSearchQuery(string query, int skipCount, int limitCount)
{
var filter = Builders<SomeType>.Filter.Text(query);
return _someTypes
.Aggregate()
// Sadly, we must create the query every time because we don't have a way to pass in
// a filter to an already created query, or change the properties of the filter.
.Match(filter)
// Currently the null coalescing operator (??) is not supported in match expressions
// see https://jira.mongodb.org/browse/CSHARP-2708
// Currently there is no way to "inject" the text search score
// see https://jira.mongodb.org/browse/CSHARP-2707
.AppendStage<SomeType>("{$addFields: {score: {$meta:'textScore'}}}")
.Sort(_sort)
.Skip(skipCount)
.Limit(limitCount);
}