I'm doing some tests to change my architecture. We want to drop MongoDB and use ElasticSearch instead. But I dont really know this technology. I'm using NEST as driver and can't translate a query that I used to use in mongo.
public async Task<IEnumerable<Keyword>> GetKeywordsAsync(string prefix, int startIndex, int totalItems, int minimumTotalSearch, CancellationToken cancellationToken)
{
return await _mongoReader.GetEntitiesAsync<KeywordEntity, Keyword>(CollectionName,
queryable =>
queryable.Where(entity => entity.KeywordName.StartsWith(prefix) && entity.TotalSearch >= minimumTotalSearch)
.OrderBy(entity => entity.KeywordName)
.Select(_keywordConverter.GetConverter())
.Skip(startIndex)
.Take(totalItems),
cancellationToken).ConfigureAwait(false);
}
public async Task<IEnumerable<TModel>> GetEntitiesAsync<TDocument, TModel>(string collectionName,
Func<IMongoQueryable<TDocument>, IMongoQueryable<TModel>> getQueryable,
CancellationToken cancellationToken)
{
var documents = GetDocuments<TDocument>(collectionName);
var query = getQueryable(documents.AsQueryable());
return await query.ToListAsync(cancellationToken).ConfigureAwait(false);
}
And here is a simple find that I made for ElasticSearch :
public async Task<IEnumerable<TModel>> FindAsync<TModel, TValue>(string index,
Expression<Func<TModel, TValue>> findExpression, TValue value, int limit,
CancellationToken cancellationToken) where TModel : class
{
var searchRequest = new SearchRequest<TModel>(index)
{
Query =
Query<TModel>.Match(
a => a.Field(findExpression).Query(string.Format(CultureInfo.InvariantCulture, "{0}", value))),
Size = limit
};
var resGet = await _elasticClientFactory.Create().SearchAsync<TModel>(searchRequest, cancellationToken).ConfigureAwait(false);
return resGet?.Documents;
}
The problem is I can't translate my Query Mongo in Elastic ...
It was painfull but here is the elastic Query :
{
"query": {
"bool": {
"must": [
{"range" : { "totalSearch" : { "gte" : minimumTotalSearch }}},
{"prefix": { "keywordName": prefix}}
]
}
},
"from": startIndex,
"size": totalItems
}
--> Solution : After some struggle-coding I found a way to do the query in C# :
var result =
ecf.Create()
.Search<KeywordEntity>(
a => a.Query(
z =>
z.Bool(
e =>
e.Must(r => r.Range(t => t.Field(y => y.TotalSearch).GreaterThanOrEquals(minimumTotalSearch)),
t => t.Prefix(y => y.KeywordName, prefix)))).Index("keywords"));
But now I'm asking myself if this is the best way to do this query (without skip/take which is quite easy). As I'm new there is maybe a more optimized query ...