You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:05:38