Skip to content

Commit

Permalink
test: demonstrate opensearch-projectGH-128 is a feature, not a bug
Browse files Browse the repository at this point in the history
Further investigation shows that a TermQuery with an empty
string value is expected to be 'conditionless' in this
codebase and the TermQuery implementation includes a
.Verbatim() method to allow the client to serialize
the query clause even though it evaluates to
conditionless

this allows me to create a query like this

    GET /index/_search
    {
      "query": {
        "bool": {
          "must": [
            {"exists": { "field": "last_name"}}
          ],
          "must_not": [
            {"term": {"last_name.keyword": {"value": ""}}}
          ]
        }
      }
    }

using the following syntax

    client.Search<SampleDomainObject>(s => s
      .Query(q => q
        .Bool(b => b
          .Must(m => m.Exists(e => e.Field("last_name")))
          .MustNot(m => m.Term(t => t.Verbatim().Field("last_name.keyword").Value(string.Empty)))
        )
      )
      .Index("index")
      .Source(sfd => null)
    );

thus resolving that opensearch-projectGH-281 is not a bug and is working as designed.

Signed-off-by: David Alpert <[email protected]>
  • Loading branch information
davidalpert committed Jul 20, 2023
1 parent 0001742 commit 64b7e75
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions tests/Tests.Reproduce/GitHubIssue281.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class SampleDomainObject
}

[U]
public void GithubIssu281_MustNotWithTermQueryAndEmptyValueShouldBeInRequestBody()
public void GithubIssu281_MustNotWithTermQueryAndVerbatimEmptyValueShouldBeInRequestBody()
{
var connectionSettings = new ConnectionSettings(new InMemoryConnection()).DisableDirectStreaming();
var client = new OpenSearchClient(connectionSettings);
Expand All @@ -60,7 +60,7 @@ public void GithubIssu281_MustNotWithTermQueryAndEmptyValueShouldBeInRequestBody
.Query(q => q
.Bool(b => b
.Must(m => m.Exists(e => e.Field("last_name")))
.MustNot(m => m.Term(t => t.Field("last_name.keyword").Value(string.Empty)))
.MustNot(m => m.Term(t => t.Verbatim().Field("last_name.keyword").Value(string.Empty)))
)
)
.Index("index")
Expand All @@ -76,13 +76,13 @@ public void GithubIssu281_MustNotWithTermQueryAndEmptyValueShouldBeInRequestBody
}

[U]
public void GithubIssue281_MustNotTermQueryAndEmptyValueShouldBeRegisteredAsNonNull()
public void GithubIssue281_MustNotTermQueryAndVerbatimEmptyValueShouldBeRegisteredAsNonNull()
{
Func<SearchDescriptor<SampleDomainObject>, ISearchRequest> selector = s => s
.Query(q => q
.Bool(b => b
.Must(m => m.Exists(e => e.Field("last_name")))
.MustNot(m => m.Term(t => t.Field("last_name.keyword").Value(string.Empty)))
.MustNot(m => m.Term(t => t.Verbatim().Field("last_name.keyword").Value(string.Empty)))
)
)
.Index("index")
Expand All @@ -97,18 +97,18 @@ public void GithubIssue281_MustNotTermQueryAndEmptyValueShouldBeRegisteredAsNonN

// this too...
query.Bool.MustNot.Should().NotBeEmpty();
// ... but this is fails as the collection contains one `<null>` entry which explains why it's missing from the serialized request JSON
// ... and this passes so long as `.Verbatim()` is used in the `TermQuery`
query.Bool.MustNot.First().Should().NotBeNull("MustNot");
}

[U]
public void GithubIssue281_MustNotTermQueryAndNonEmptyValueShouldBeRegisteredAsNonNull()
public void GithubIssue281_MustNotTermQueryAndNonVerbatimEmptyValueShouldBeRegisteredAsNonNull()
{
Func<SearchDescriptor<SampleDomainObject>, ISearchRequest> selector = s => s
.Query(q => q
.Bool(b => b
.Must(m => m.Exists(e => e.Field("last_name")))
.MustNot(m => m.Term(t => t.Field("last_name.keyword").Value("mal")))
.MustNot(m => m.Term(t => t.Verbatim().Field("last_name.keyword").Value("mal")))
)
)
.Index("index")
Expand Down Expand Up @@ -164,10 +164,10 @@ public void GithubIssue281_TermQueryWithNonEmptyValueSerializesToNonNullResult()
}

[U]
public void GithubIssue281_TermQueryWithEmptyValueSerializesToNonNullResult()
public void GithubIssue281_TermQueryWithVerbatimEmptyValueSerializesToNonNullResult()
{
Func<QueryContainerDescriptor<SampleDomainObject>, QueryContainer> termQuery =
m => m.Term(t => t.Field("last_name.keyword").Value(string.Empty));
m => m.Term(t => t.Verbatim().Field("last_name.keyword").Value(string.Empty));

var result = termQuery.Invoke(new QueryContainerDescriptor<SampleDomainObject>());

Expand All @@ -177,7 +177,7 @@ public void GithubIssue281_TermQueryWithEmptyValueSerializesToNonNullResult()
[TU]
[InlineData("null", null, true)]
[InlineData("non-empty string", "doe", false)]
[InlineData("empty string", "", false)]
[InlineData("empty string", "", true)]
public void GithubIssue281_TermQueryIsConditionless(string scenario, string val, bool expected)
{
bool SimulateIsConditionless(ITermQuery q)
Expand Down

0 comments on commit 64b7e75

Please sign in to comment.