Search code examples
c#asp.netelasticsearchdslelasticsearch-dsl

Build Dynamic ElasticSearch query using OR clause in C#


The following is a query written in C#. It leverages Elastic.Clients.Elasticsearch version 8.13.7. This is NOT the NEST client. This is the ASP.NET client. It doesn't have a lot of documentation.

submissions = await localClient.SearchAsync<SubmissionDto>(SUBMISSION_INDEX, s => s
   .Query(q => q
      .Bool(b => b
         .Must(
            m => m.Term(tt => tt.Field(f => f.Ori).Value(myTenants.ElementAt(0).Item1.ToLower())),
            m => m.Term(tt => tt.Field(f => f.Cri).Value(myTenants.ElementAt(0).Item2.ToLower())))
         .Filter(f => f
            .Range(rr => rr
               .DateRange(dr => dr
                 .Field(f => f.SubmissionCreation)
                   .Gte(startDate.ToString("yyyy/MM/dd"))
                   .Lte(endDate.ToString("yyyy/MM/dd"))
                    .TimeZone("America/New_York"))))))
    .Size(MAX_DOCUMENTS)
    .Sort(sort => sort
        .Field(f => f.SubmissionCreation, d => d
        .Order(SortOrder.Desc))));

The query uses myTenants which is passed in as a parameter to the method. The type of myTenants is IEnumerable<Tuple<string, string>>. Each item in the list represents and ORI/CRI pair. I need to update the query to traverse the entire myTenants list. The query should return all SubmissionDto where the ORI/CRI combination is equal to those in myTenants

I've tried a bunch of different queries


Solution

  • My understanding of your question is you would like to retrieve all documents that have the same key value pairs. So a query something like this?

    (Ori = A && Cri = B) || (Ori = C && Cri = D) || ...
    

    This can be written like so:

    await client.SearchAsync<SubmissionDto>("indexname", s => s
        .Query(q => q
            .Bool(b => b
                .Should(
                    tenants.Select<Tenant, Action<QueryDescriptor<SubmissionDto>>>(tenant => d => d.
                        Bool(b => b
                            .Must(
                                m => m.Term(t => t.Field(dto => dto.Ori).Value(tenant.Ori)),
                                m => m.Term(t => t.Field(dto => dto.Cri).Value(tenant.Cri))
                            )
                        )
                    ).ToArray()
                )
            )
        )
    );