# Boolean Queries in Net Client

**URL:** https://discuss.elastic.co/t/boolean-queries-in-net-client/364337
**Category:** Elasticsearch
**Tags:** language-clients
**Created:** [August 4, 2024, 7:23pm UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337 "2024-08-04T19:23:45Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![alikleitcr7](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alikleitcr7/32/136346_2.png) [@alikleitcr7](https://discuss.elastic.co/u/alikleitcr7)
#### Post date: [August 4, 2024, 7:23pm UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/1 "2024-08-04T19:23:45Z")

</div>

Hello,

As pointed out by @flobernd in my [Github Issue](https://github.com/elastic/elasticsearch-net/issues/8272) related to working with the latest net client that the documentation for the latest is very sparse. Therefore, I'm trying to manage the `AND` operator in the `Bool` query, and it's quite different from the ones before [Net API 5.x](https://www.elastic.co/guide/en/elasticsearch/client/net-api/5.x/bool-queries.html) where we can use the `&&` and `||` operators, Plus I tried the straight forward approach as I understoon that "the new client (starting from version 8.13) closely maps to the structure of the REST JSON structure":

```cs
 SearchResponse<PostDocument> searchResponse3 = await elasticsearchClient.SearchAsync<PostDocument>(s => s
     .Index(indexName)
     .From(0)
     .Size(10)
     .Query(q =>
     {
         q.Nested(n =>
         {
             //n.IgnoreUnmapped();
             n.Path(p => p.Categories)
             .Query(nq =>
             {
                 nq.Bool(b =>
                 {
                     b.Must(m =>
                     {
                         m.Match(mt =>
                         {
                             mt.Field(f => f.Categories.First().CategoryId)
                             .Query(category_dystopian.CategoryId.ToString());
                         });

                         m.Match(mt =>
                         {
                             mt.Field(f => f.Categories.First().CategoryId)
                             .Query(category_tragedy.CategoryId.ToString());
                         });
                     });
                 });
             });
         });
     })
 );

```

Debugging it would be:

```json
{
  "query": {
    "nested": {
      "query": {
        "bool": {
          "must": {
            "match": {
              "categories.categoryId": {
                "query": "1a36c19d-8210-4e65-9cda-ca8c9c0ec04e"
              }
            }
          }
        }
      },
      "path": "categories"
    }
  },
  "from": 0,
  "size": 10
}

```

NESTED is already mapped, it gets just one category but does not perform the AND, as it only generated 1 line of match which should have been 2.

Unless there is a different way to implement `AND` , `OR` ?

Appreciated!

---

<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: [August 5, 2024, 7:09am UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/2 "2024-08-05T07:09:47Z")

</div>

Hi @alikleitcr7 ,

your query was nearly correct.

Using `m.Match` on **the same** query descriptor 2 times, causes it to _change_ it's content and only keep the configuration from the last invocation.

Instead, the `params`/array overload must be used:

csharp

```auto
SearchResponse<PostDocument> searchResponse3 = await client.SearchAsync<PostDocument>(s => s
	.Index(indexName)
	.From(0)
	.Size(10)
	.Query(q => q
		.Nested(n => n
			.Path(p => p.Categories)
			.Query(nq => nq
				.Bool(b => b
					.Must(
						// <- use the "params" overload
						m => m
							.Match(mt => mt
								.Field(f => f.Categories.First().CategoryId)
								.Query(category_dystopian.CategoryId.ToString())
							),
						m => m
							.Match(mt => mt
								.Field(f => f.Categories.First().CategoryId)
								.Query(category_tragedy.CategoryId.ToString())
							)
					)
				)
			)
		)
	)
);

```

---

<div class="post-metadata">

### Author: ![alikleitcr7](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alikleitcr7/32/136346_2.png) [@alikleitcr7](https://discuss.elastic.co/u/alikleitcr7)
#### Post date: [August 9, 2024, 6:21pm UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/3 "2024-08-09T18:21:19Z")

</div>

Thanks @flobernd !

I tried, and it resulted to the expected request query. However, is it correct that this is an AND? as it seems to not return any result. only when removing either one of the items. I tried with term as well, and removing the `query` by setting the value directly to the field as follows:

```auto
GET /test-posts/_search
{
  "query": {
    "nested": {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "categories.categoryId": "e5109ad9-9a73-4606-b4f8-c0130fbadcd9"
              }
            },
            {
              "term": {
                "categories.categoryId": "1a36c19d-8210-4e65-9cda-ca8c9c0ec04e"
              }
            }
          ]
        }
      },
      "path": "categories"
    }
  },
  "from": 0,
  "size": 10
}

```

results to:

```auto
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

```

given the following document:

```auto
{
  ...
  title: "Animal Farm",
  ....,
  categories: [
    {
      "categoryId": "e5109ad9-9a73-4606-b4f8-c0130fbadcd9",
      "title": "Dystopian",
    },
    {
      "categoryId": "1a36c19d-8210-4e65-9cda-ca8c9c0ec04e",
      "title": "Tragedy",
    }
  ]
},
...

```

with mapping:

 ![image](https://us1.discourse-cdn.com/elastic/original/3X/8/0/80954b056e70258c73e0441d7baa6124f4e1418a.png)

---

<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: [August 10, 2024, 2:44pm UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/4 "2024-08-10T14:44:55Z")

</div>

@alikleitcr7 Yes, this is what AND does 😅 It only returns the results for which „all“ query conditions are matching.

In your case, you specify 2 different ids for the same field, which means that your condition is never true.

If you want to return documents with either id1 or id2 you would have to use OR (as this will return all documents for which „at least one“ of the conditions are matching).

I’m only on mobile right now and sadly can’t help you with the syntax for your case where you want to check the existence of 2 specific items in the nested array.

---

<div class="post-metadata">

### Author: ![alikleitcr7](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alikleitcr7/32/136346_2.png) [@alikleitcr7](https://discuss.elastic.co/u/alikleitcr7)
#### Post date: [August 11, 2024, 11:39am UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/5 "2024-08-11T11:39:58Z")

</div>

Interesting, I am aiming for something like `contains`. where the list of ids do exist in the nested array.

Then the following example also is never True [Here](https://www.elastic.co/guide/en/elasticsearch/client/net-api/5.x/bool-queries.html#binary-and-operator)?

An OR would not be the case, as it will get other documents with either ID1 or ID2 in their list.

I also tried using `terms` + `keyword`:

```auto
GET /test-posts/_search
{
 "query": {
    "nested": {
      "path": "categories",
      "query": {
        "bool": {
          "must": [
            {
              "terms": {
                "categories.categoryId.keyword": [
                  "e5109ad9-9a73-4606-b4f8-c0130fbadcd9",
                  "1a36c19d-8210-4e65-9cda-ca8c9c0ec04e" ]
              }
            }
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 10
}

```

and an `OR` inside the `AND`

```auto
GET /test-posts/_search
{
 "query": {
    "nested": {
      "path": "categories",
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "term": {
                      "categories.categoryId": {
                        "value": "e5109ad9-9a73-4606-b4f8-c0130fbadcd9"
                      }
                    }
                  },
                    {
                    "term": {
                      "categories.categoryId": {
                        "value": "1a36c19d-8210-4e65-9cda-ca8c9c0ec04e"
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 10
}

```

Is there a specific way to handle AND on the same field in an array?

---

<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: [August 12, 2024, 11:07am UTC](https://discuss.elastic.co/t/boolean-queries-in-net-client/364337/6 "2024-08-12T11:07:59Z")

</div>

> [@alikleitcr7](#):
>
> Then the following example also is never True [Here](https://www.elastic.co/guide/en/elasticsearch/client/net-api/5.x/bool-queries.html#binary-and-operator)?

Yes, that example is as well slightly misleading as the condition can never be `true`.

I'm sorry, I think I missed the `nested` part in your initial query.

From this [SO comment](https://stackoverflow.com/a/63139437), the correct solution would be to build the query chain like this (pseudo code):

```auto
.Must(
  .Nested(
    .Term("categories.categoryId", "id1")
  ),
  .Nested(
    .Term("categories.categoryId", "id2")
  ),
)

```

So basically use the `Must/AND` query on the first level and put multiple `Nested->Term` queries inside.
