0

I have the following Query that I am building up, notice that filtering on the companyGroupId I cant seem to find suitable way to add and conditional Term.

I would like to check the includeTerminationDate value and conditionally add the term

So in a nutshell, if false don't return records with an termination date.

private Func<QueryContainerDescriptor<EmployeeDocument>, QueryContainer> EmployeeSearchQuery(string query, long companyGroupId, bool includeTerminationDate)
        {
            return q => q
                            .MultiMatch(m => m
                                .Query(query)

                                .Type(TextQueryType.MostFields)
                                .MinimumShouldMatch("90%")
                                .Fields(f => f
                                    .Field(ff => ff.FullName, 3)
                                    .Field(ff => ff.Number, 3)
                                    .Field(ff => ff.Email)
                                    .Field(ff => ff.JobNumber)
                                    .Field(ff => ff.Description))) && q.Term(f => f.CompanyGroupId, companyGroupId);
        }

The one why would just be to duplicate the code and add the Term per the condition. But i would like to keep to the DRY Principle. The other way would be something like the below, which I cant seem to figure out.

return q => q
                            .MultiMatch(m => m
                                .Query(query)

                                .Type(TextQueryType.MostFields)
                                .MinimumShouldMatch("90%")
                                .Fields(f => f
                                    .Field(ff => ff.FullName, 3)
                                    .Field(ff => ff.Number, 3)
                                    .Field(ff => ff.Email)
                                    .Field(ff => ff.JobNumber)
                                    .Field(ff => ff.Description))) && q.Term(f => f.CompanyGroupId, companyGroupId)
                                                                     && !includeTerminationDate ? q.Term(f => f.TerminationDate, null) : 'Otherwise do not include term';

1 Answer 1

3

One way to achieve this would be to convert the expression to a method group, and conditionally add the query

private Func<QueryContainerDescriptor<EmployeeDocument>, QueryContainer> EmployeeSearchQuery(string query, long companyGroupId, bool includeTerminationDate)
{
    return q =>
    {
        var qc = q.MultiMatch(m => m
                   .Query(query)
                   .Type(TextQueryType.MostFields)
                   .MinimumShouldMatch("90%")
                   .Fields(f => f
                       .Field(ff => ff.FullName, 3)
                       .Field(ff => ff.Number, 3)
                       .Field(ff => ff.Email)
                       .Field(ff => ff.JobNumber)
                       .Field(ff => ff.Description))) && 
                q.Term(f => f.CompanyGroupId, companyGroupId);

        // whatever your logic is for adding termination date
        if (includeTerminationDate)
            qc &= q.Term(f => f.TerminationDate, DateTime.UtcNow);

        return qc;
    };
}

Then to use

client.Search<EmployeeDocument>(s => s
    .Query(EmployeeSearchQuery("query", 2, false))
);

emits

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "type": "most_fields",
            "query": "query",
            "minimum_should_match": "90%",
            "fields": [
              "fullName^3",
              "number^3",
              "email",
              "jobNumber",
              "description"
            ]
          }
        },
        {
          "term": {
            "companyGroupId": {
              "value": 2
            }
          }
        }
      ]
    }
  }
}

and

client.Search<EmployeeDocument>(s => s
    .Query(EmployeeSearchQuery("query", 2, true))
);

emits

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "type": "most_fields",
            "query": "query",
            "minimum_should_match": "90%",
            "fields": [
              "fullName^3",
              "number^3",
              "email",
              "jobNumber",
              "description"
            ]
          }
        },
        {
          "term": {
            "companyGroupId": {
              "value": 2
            }
          }
        },
        {
          "term": {
            "terminationDate": {
              "value": "2018-05-16T23:21:16.8309753Z"
            }
          }
        }
      ]
    }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Ah is that how you do it I was struggling to add the condition did not realize I could just change it to an Method group
lambdas upon lambdas :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.