elasticsearch-net icon indicating copy to clipboard operation
elasticsearch-net copied to clipboard

NEST Client does not adhere to scoped type.

Open coding-red-panda opened this issue 2 years ago • 0 comments

NEST/Elasticsearch.Net version: 7.15.5

Elasticsearch version: 8.10.4

.NET runtime version: .NET 5

Operating system version: Irrelevant

Description of the problem including expected versus actual behavior: When generating queries using Nest, you can set the generic type parameter when making calls. See the code below:

var response = await _client.DeleteByQueryAsync<T>(descriptor => descriptor
                .Index(indexName.ToString())
                .Query(query => query.HasParent<Company>(selector => selector
                    .ParentType("company")
                    .Query(parentQuery => parentQuery
                        .Terms(terms => terms
                            .Field(company => company.UniqueId)
                            .Terms(companyUniqueIds.Select(x=>x.ToString()).ToArray())
                        )
                    )
                ))
            , cancellationToken).ConfigureAwait(false);

Expected behavior

The idea here is that we delete all documents of a specific type that have a specific parent document. E.g. when the generic type T is set to Person, we expect Nest to generate a query that only deletes Person documents from ElasticSearch inferring the types from the generic arguments.

However, the query being generated is this:

{"query":{"has_parent":{"parent_type":"company","query":{"terms":{"uniqueId":["cz-company-01308963"]}}}}}

This simply deletes ALL child documents from ElasticSearch, completely ignoring the inferred type. We have to rewrite the query like this to make it work:

var response = await _client.DeleteByQueryAsync<T>(descriptor => descriptor
                .Index(indexName.ToString())
                .Query(query => query
                    .Bool(bs => bs
                        .Must(
                            x => x
                                .HasParent<Company>(selector => selector
                                .ParentType("company")
                                .Query(parentQuery => parentQuery
                                    .Terms(terms => terms
                                        .Field(company => company.UniqueId)
                                        .Terms(companyUniqueIds.Select(uniqueIds => uniqueIds.ToString()).ToArray())
                                    )
                                )
                            ),
                            x => x.Term(term => term.Field("type").Value(typeof(T).Name.ToLower()))
                        )
                    ))
            , cancellationToken).ConfigureAwait(false);

What we expect is the following:

  • If documents have a JoinField defined, Nest should be able to add the Term constrain on its own to scope queries to the specific type.
  • The ParentType must be set manually, doesn't matter whether we use the <Company> type, it only helps in fluent code type hinting.

coding-red-panda avatar Dec 06 '23 07:12 coding-red-panda