Elasticsearch.NET.InMemoryConnection未在responseData上应用筛选器。

huangapple go评论67阅读模式
英文:

Elasticsearch.NET.InMemoryConnection not applying filters on responseData

问题

以下是您要翻译的代码部分:

我有一个来自Elasticsearch.Net的Elastic Client,它从InMemoryConnection获取数据并在搜索上添加查询过滤器,但结果未进行过滤。它将整个响应主体作为结果返回。

我是否遗漏了什么,或者这就是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();

希望这对您有所帮助。

英文:

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 = &quot;CCY&quot;)]
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&lt;CurrenciesDTO&gt; listCurrencies = new List&lt;CurrenciesDTO&gt; { new CurrenciesDTO() { CCY = &quot;GEL&quot; }, new CurrenciesDTO() { CCY = &quot;INR&quot; }, new CurrenciesDTO() { CCY = &quot;JPY&quot; }, new CurrenciesDTO() { CCY = &quot;USD&quot; } };
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 = &quot;eq&quot;
},
max_score = 1.0,
hits = Enumerable.Range(0, listCurrencies.Count).Select(i =&gt; (object)new
{
_index = &quot;test.my.currencies&quot;,
_type = &quot;_doc&quot;,
_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 =&gt;
{
if (apiCallDetails.RequestBodyInBytes != null)
{// not reaching here
Console.WriteLine(
$&quot;{apiCallDetails.HttpMethod} {apiCallDetails.Uri} &quot; +
$&quot;{Encoding.UTF8.GetString(apiCallDetails.RequestBodyInBytes)}&quot;);
}
});
var client = new ElasticClient(connectionSettings);
var filterItems = new List&lt;Func&lt;QueryContainerDescriptor&lt;CurrenciesDTO&gt;, QueryContainer&gt;&gt;();
filterItems.Add(p =&gt; p.Term(v =&gt; v.Field(f=&gt;f.CCY).Value(&quot;USD&quot;)));
var result = await client.SearchAsync&lt;CurrenciesDTO&gt;(s =&gt; s
.Index(&quot;test.my.currencies&quot;)
.Query(q =&gt; q.Bool(x =&gt; x.Filter(filterItems))), CancellationToken.None);
// .Query(q =&gt; q.Term(p =&gt; p.CCY, &quot;USD&quot;)));
//expected 1 record but 4 records are returned.    
foreach (var a in result.Documents.ToArray())
{
Console.WriteLine(a.CCY);
}
Console.ReadLine();

答案1

得分: 3

这是按设计要求的。 InMemoryConnection 是为了更容易进行单元测试而创建的,并不能帮助验证实际查询的有效性。

为确保Elasticsearch配置符合您的预期,以及查询发送到Elasticsearch的有效性,我建议使用Testcontainers

简单的测试步骤如下:

  • 使用Testcontainers启动一个新的Elasticsearch Docker实例

  • 索引一些数据

  • 运行您的代码针对运行在容器内的Elasticsearch

英文:

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

huangapple
  • 本文由 发表于 2023年2月10日 15:09:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75407931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定