# Elasticsearch .net v8 and operator

**URL:** https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496
**Category:** Elasticsearch
**Tags:** language-clients
**Created:** [June 14, 2024, 1:05pm UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496 "2024-06-14T13:05:10Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Odd\_Erik\_Gronberg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/odd_erik_gronberg/32/52179_2.png) [@Odd\_Erik\_Gronberg](https://discuss.elastic.co/u/Odd_Erik_Gronberg)
#### Post date: [June 14, 2024, 1:05pm UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496/1 "2024-06-14T13:05:10Z")

</div>

Hi, just started porting our ES facing code from NEST to the new V8 client. I am facing some issues that I would like to get some input on.

In NEST I am able to use the AND operator to "join" multiple QueryContainers like this:

```auto
        public class TrackingEvent
        {
           public string SessionKey { set; get; }
           public string Email { set; get; }
        }

        private QueryContainer CreateQueryContainer(string email, string sessionKey)
        {

            QueryContainerDescriptor<TrackingEvent> queryContainerDescriptor = new QueryContainerDescriptor<TrackingEvent>();
            QueryContainer queryContainer = new QueryContainer();

            if (!string.IsNullOrEmpty(sessionKey))
            {
                var queryDescriptor = new TermQueryDescriptor<TrackingEvent>();
                queryDescriptor.Field(x => x.SessionKey).Value(sessionKey);
                queryContainer &= queryContainerDescriptor.Term(x => queryDescriptor);
            }

            if (!string.IsNullOrEmpty(email))
            {
                var queryDescriptor = new TermQueryDescriptor<TrackingEvent>();
                queryDescriptor.Field(x => x.Email).Value(email);
                queryContainer &= queryContainerDescriptor.Term(x => queryDescriptor);
            }

            return queryContainer;
        }

```

I have a hard time finding out how I can achieve the same thing in the V8 client.

Any help and guidance is highly appreciated here.

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: [June 17, 2024, 7:17am UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496/2 "2024-06-17T07:17:06Z")

</div>

Hi @Odd_Erik_Gronberg,

these operators are shortcuts for a `BoolQuery` (either `should` or `must`). The `QueryContainerDescriptor` is now called `QueryDescriptor` and the corresponding non-fluent class is just `Query`. The latter one still supports these operators, but for the descriptors they are not available at the moment.

You could either change your code to use `Query` instead of the descriptors, or probably even better (based on the code snippet you posted), keep building the individual queries for `sessionKey` and `email`, store then in a list and create the "container" in the very end using a single `Query.Bool(...Must(queryList))`.

---

<div class="post-metadata">

### Author: ![Odd\_Erik\_Gronberg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/odd_erik_gronberg/32/52179_2.png) [@Odd\_Erik\_Gronberg](https://discuss.elastic.co/u/Odd_Erik_Gronberg)
#### Post date: [June 17, 2024, 2:55pm UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496/3 "2024-06-17T14:55:07Z")

</div>

Thanks @flobernd !

The query approach would work but we will miss the strongly typed field name we get through the generic descriptors. I found a workaround for this using the Infer.Field for the corresponding class instead, but preferably we would continue to use the fluent descriptors.

I am not quite able to figure out how to implement the second approach you suggest here. Are you referring to the usage of:

```auto
	public BoolQueryDescriptor<TDocument> Must(params Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>>[] configure)
	{
		MustValue = null;
		MustDescriptor = null;
		MustDescriptorAction = null;
		MustDescriptorActions = configure;
		return Self;
	}

```

when passing a query list here?

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: [June 18, 2024, 6:58am UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496/4 "2024-06-18T06:58:39Z")

</div>

Hi @Odd_Erik_Gronberg,

at the moment it's kinda hard to mix fluent and object syntax.

> [@Odd\_Erik\_Gronberg](#):
>
> Are you referring to the usage of

Yes! The trick is to maintain a list of `Action<QueryDescriptor<T>>>` instead of just a list of `QueryDescriptor<T>`. Using this approach you can dynamically add or remove actions from the list, before crafting the final query descriptor that combines the sub-queries. `Must` is equivalent to `&&` and `Should` is equivalent to `||`.

```auto
var actions = new List<Action<QueryDescriptor<Person>>>()
{
	x => x.Term(x => x.Field(p => p.FirstName)),
	x => x.Term(x => x.Field(p => p.Email)),
};

var q = new QueryDescriptor<Person>().Bool(x => x.Must(actions.ToArray()));

```

---

<div class="post-metadata">

### Author: ![Odd\_Erik\_Gronberg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/odd_erik_gronberg/32/52179_2.png) [@Odd\_Erik\_Gronberg](https://discuss.elastic.co/u/Odd_Erik_Gronberg)
#### Post date: [June 18, 2024, 7:44am UTC](https://discuss.elastic.co/t/elasticsearch-net-v8-and-operator/361496/5 "2024-06-18T07:44:17Z")

</div>

Nice! Thanks for your help @flobernd !
