Elasticsearch.NET.InMemoryConnection未对响应数据应用过滤的问题
问题描述
使用Elasticsearch.Net的Elastic Client,通过InMemoryConnection获取数据时,已添加Query过滤条件,但结果未被过滤,仍返回responseBody中的全部数据。请问是遗漏了配置,还是InMemoryConnection本身就是如此工作?
代码示例
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();
解答
InMemoryConnection本身就是这样工作的——它是一个仅用于模拟响应的测试工具,不会解析或处理你发送的查询请求,不管你传入什么样的过滤条件、查询语句,它都会原封不动返回你初始化时传入的responseBody内容。
如果需要模拟查询过滤的效果,你有两个方向可选:
- 自定义实现
IConnection接口,在RequestAsync方法中解析请求的查询参数/请求体,根据查询逻辑动态生成对应的响应数据返回; - 使用Elasticsearch测试容器,启动一个真实的Elasticsearch实例进行测试,这样就能正常处理查询过滤逻辑。
内容的提问来源于stack exchange,提问作者Keppy
相关产品推荐
相关产品推荐

