Elasticsearch.NET.InMemoryConnection not applying filters on responseData

117 views Asked by At

I have a Elastic Client from Elasticsearch.Net which fetching data from InMemoryConnection and add Query filter on the search but result is not filtering. Its returning entire data from responseBody as result.

Am I missing something or this is how InMemoryConnection is working?

CurrenciesDTO.cs

internal class CurrenciesDTO
    {
        [Keyword(Name = "CCY")]
        public string CCY { get; set; }
    }

Program.cs

using ConsoleApp_Elastic;
using Elasticsearch.Net;
using Nest;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text;
using System.Threading;


List<CurrenciesDTO> listCurrencies = new List<CurrenciesDTO> { new CurrenciesDTO() { CCY = "GEL" }, new CurrenciesDTO() { CCY = "INR" }, new CurrenciesDTO() { CCY = "JPY" }, new CurrenciesDTO() { CCY = "USD" } };

var response = new
{
    took = 1,
    timed_out = false,
    _shards = new
    {
        total = 1,
        successful = 1,
        skipped = 0,
        failed = 0
    },
    hits = new
    {
        total = new
        {
            value = 193,
            relation = "eq"
        },
        max_score = 1.0,
        hits = Enumerable.Range(0, listCurrencies.Count).Select(i => (object)new
        {
            _index = "test.my.currencies",
            _type = "_doc",
            _id = listCurrencies[i].CCY,
            _score = 1.0,
            _source = new
            {
                CCY = listCurrencies[i].CCY,
            }
        })

    }

};

string json = JsonConvert.SerializeObject(response);
var responseBody =  Encoding.UTF8.GetBytes(json);

ConnectionSettings connectionSettings = new ConnectionSettings(new InMemoryConnection(responseBody, 200));
connectionSettings.OnRequestCompleted(apiCallDetails =>
{
    if (apiCallDetails.RequestBodyInBytes != null)
    {// not reaching here
        Console.WriteLine(
            $"{apiCallDetails.HttpMethod} {apiCallDetails.Uri} " +
            $"{Encoding.UTF8.GetString(apiCallDetails.RequestBodyInBytes)}");
    }
});
var client = new ElasticClient(connectionSettings);

var filterItems = new List<Func<QueryContainerDescriptor<CurrenciesDTO>, QueryContainer>>();

filterItems.Add(p => p.Term(v => v.Field(f=>f.CCY).Value("USD")));
var result = await client.SearchAsync<CurrenciesDTO>(s => s
                            .Index("test.my.currencies")
                            .Query(q => q.Bool(x => x.Filter(filterItems))), CancellationToken.None);
                           // .Query(q => q.Term(p => p.CCY, "USD")));
//expected 1 record but 4 records are returned.    
foreach (var a in result.Documents.ToArray())
    {
        Console.WriteLine(a.CCY);
    }
    Console.ReadLine();
1

There are 1 answers

0
Rob On BEST ANSWER

Yes, this is by design. InMemoryConnection was created to make unit testing easier and won't be much help with validating actual queries.

For making sure that Elasticsearch is configured the way you are expecting it to be and that queries sent to Elasticsearch are valid I would suggest using Testcontainers.

Simple test would look like:

  • spin up new docker instance of Elasticsearch with Testcontainers help
  • index some data
  • run you code against Elasticsearch running inside container