# TermsQuery class in elastic.clients.elasticsearch (8.x)

**URL:** <https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556>\
**Category:** Elasticsearch\
**Tags:** language-clients\
**Created:** [September 13, 2024, 6:50pm UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556 "2024-09-13T18:50:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![moyerskd](https://avatars.discourse-cdn.com/v4/letter/m/ec9cab/32.png) [@moyerskd](https://discuss.elastic.co/u/moyerskd)\
**Post date:** [September 13, 2024, 6:50pm UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/1 "2024-09-13T18:50:51Z")

</div>

In a .NET app, I am migrating from NEST (7.x) to Elastic.Clients.Elasticsearch (8.x). In NEST, I am dynamically building a `List<QueryContainer>` called queries. One section determines the need of a Terms query and if so, it is doing this where values is a `string[]` of values:

```auto
queries.Add(new TermsQuery
{
    Field = kvp.Key.ToSnakeCase(),
    Terms = values
});

```

The problem with (8.x) is that Terms is no longer a property of TermsQuery class.

Any suggestions or alternatives for how to do this in 8.x lib?

---

<div class="post-metadata">

**Author:** ![flobernd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flobernd/32/124877_2.png) [@flobernd](https://discuss.elastic.co/u/flobernd)\
**Post date:** [September 16, 2024, 7:08am UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/2 "2024-09-16T07:08:42Z")

</div>

Hi @moyerskd,

it should work with:

```csharp
new TermsQuery
{
  // ...
  Term = new TermsQueryField(values)
}

```

---

<div class="post-metadata">

**Author:** ![moyerskd](https://avatars.discourse-cdn.com/v4/letter/m/ec9cab/32.png) [@moyerskd](https://discuss.elastic.co/u/moyerskd)\
**Post date:** [September 16, 2024, 1:42pm UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/3 "2024-09-16T13:42:51Z")

</div>

Hi, and thank you for the reply. I have tried that, but TermsQueryField only takes a readonly collection of FieldValue. The values I'm trying to use are `string[]`. Is there some other way?

Thanks!

---

<div class="post-metadata">

**Author:** ![moyerskd](https://avatars.discourse-cdn.com/v4/letter/m/ec9cab/32.png) [@moyerskd](https://discuss.elastic.co/u/moyerskd)\
**Post date:** [September 16, 2024, 8:24pm UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/4 "2024-09-16T20:24:10Z")

</div>

Can it be done like this?

```auto
var terms = new ReadOnlyCollection<FieldValue>(new List<FieldValue>
{
    "some value"
});
queries.Add(new TermsQuery
{
    Field = kvp.Key,
    Term = new TermsQueryField(terms)
});

```

Also, in NEST, we were able to create a "must\_not" by doing this. With the bang in front of the new TermsQuery.

```auto
queries.Add(!new TermQuery(kvp.Key.ToSnakeCase())
{
    Field = kvp.Key.ToSnakeCase(),
    Terms = values

});

```

It doesn't allow this in 8.x. Is there an equivalent to that process?

Thanks!

---

<div class="post-metadata">

**Author:** ![flobernd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flobernd/32/124877_2.png) [@flobernd](https://discuss.elastic.co/u/flobernd)\
**Post date:** [September 17, 2024, 7:54am UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/5 "2024-09-17T07:54:38Z")

</div>

Hi @moyerskd,

> [@moyerskd](#):
>
> The values I'm trying to use are `string[]`. Is there some other way?

`FieldValue` can be constructed from `string`, so you might want to cast it before passing it to the `TermsQueryField` constructor:

```csharp
new TermsQueryField(values.Select(x => (FieldValue)x))

```

> [@moyerskd](#):
>
> Can it be done like this?

This does as well work, yes!

> [@moyerskd](#):
>
> It doesn't allow this in 8.x. Is there an equivalent to that process?

This feature is currently not implemented yet. In the meantime you have to use the verbose query like this:

```csharp
.Bool(b => b
    .MustNot(q => q
        .Term(t => ...)
    )
)

```

---

<div class="post-metadata">

**Author:** ![moyerskd](https://avatars.discourse-cdn.com/v4/letter/m/ec9cab/32.png) [@moyerskd](https://discuss.elastic.co/u/moyerskd)\
**Post date:** [September 17, 2024, 10:27pm UTC](https://discuss.elastic.co/t/termsquery-class-in-elastic-clients-elasticsearch-8-x/366556/6 "2024-09-17T22:27:58Z")

</div>

Thank you! Your help has been invaluable. If you wouldn't mind, will you assist with this one? Below the ` SearchDescriptor<T>` and `IPromise<>` are old concepts in NEST. What are the equivalents to these in 8.x? Also, how to use the `CountDescriptor<>`?

Thanks!

NEST:

```auto
Func<SearchDescriptor<T>, Elastic.Clients.Elasticsearch.SearchRequest> search = (s) =>
{
    var r = s.Query(q => q.QueryString(d => d.Query(query))).Size(pagingInfo.Size);

    if (!string.IsNullOrEmpty(pit) && pagingInfo.Enabled)
    {
        Logger.LogDebug("Point in time included on search of index '{Index}'", indexName);
        s.PointInTime(pit);
    }
    else
    {
        s.Index(index);
    }

    if (pagingInfo.SortFilters == null || !pagingInfo.SortFilters.Any())
    {
        pagingInfo.SortFilters = new Dictionary<string, bool> { { "id", true } };
    }

    s.Sort((sort) =>
    {
        return (IPromise<IList<ISort>>)CreateSort(pagingInfo.SortFilters);
    });

    if (afterKeys?.Count > 0)
    {
        Logger.LogDebug("Search after included on search of index '{Index}'", indexName);
        s.SearchAfter(ScrubPagingAfterKeys(afterKeys));
    }

    return r;
};

```
