Skip to content

Commit

Permalink
Added .Strict(...), .Verbatim(...), .Name(...) methods on `Quer…
Browse files Browse the repository at this point in the history
…yContainer` to help modify contained query attributes. (#375) (#509) (#539)

Signed-off-by: Kostas <[email protected]>
(cherry picked from commit e4f715e)

Co-authored-by: DumboJetEngine <[email protected]>
  • Loading branch information
Xtansia and DumboJetEngine authored Feb 7, 2024
1 parent e251448 commit 08ce783
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]
### Added
- Added `.Strict(...)`, `.Verbatim(...)`, `.Name(...)` methods on `QueryContainer` to help modify contained query attributes ([#509](https://github.com/opensearch-project/opensearch-net/pull/509))

### Fixed
- Fixed `IEnumerable<int?>` property mapping. ([#503](https://github.com/opensearch-project/opensearch-net/pull/503))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,58 @@ out QueryContainer queryContainer

// ReSharper disable once UnusedMember.Global
internal bool ShouldSerialize(IJsonFormatterResolver formatterResolver) => IsWritable;

/// <summary>
/// Assigns a name to the contained query.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public QueryContainer Name(string name)
{
ContainedQuery.Name = name;
return this;
}

/// <summary>
/// Applies or removes the `strict` attribute to the contained query and optionally to all child sub-queries.
/// </summary>
/// <param name="strict"></param>
/// <param name="recurse">When true, it applies the attribute to all child sub-queries.</param>
/// <returns></returns>
public QueryContainer Strict(bool strict = true, bool recurse = false)
{
if (recurse)
{
var visitor = new StrictnessPropagatingVisitor(strict);
Accept(visitor);
}
else
{
ContainedQuery.IsStrict = strict;
}

return this;
}

/// <summary>
/// Applies or removes the `verbatim` attribute to the contained query and optionally to all child sub-queries.
/// </summary>
/// <param name="verbatim"></param>
/// <param name="recurse">When true, it applies the attribute to all child sub-queries.</param>
/// <returns></returns>
public QueryContainer Verbatim(bool verbatim = true, bool recurse = false)
{
if (recurse)
{
var visitor = new VerbatimPropagatingVisitor(verbatim);
Accept(visitor);
}
else
{
ContainedQuery.IsVerbatim = verbatim;
}

return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

using System;

namespace OpenSearch.Client
{
public class StrictnessPropagatingVisitor : QueryVisitor
{
private readonly bool _strict;

public StrictnessPropagatingVisitor(bool strict) => _strict = strict;

public override void Visit(IQuery query)
{
query.IsStrict = _strict;
base.Visit(query);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

namespace OpenSearch.Client
{
public class VerbatimPropagatingVisitor : QueryVisitor
{
private readonly bool _verbatim;

public VerbatimPropagatingVisitor(bool verbatim) => _verbatim = verbatim;

public override void Visit(IQuery query)
{
query.IsVerbatim = _verbatim;
base.Visit(query);
}
}
}
102 changes: 102 additions & 0 deletions tests/Tests/QueryDsl/Container/QueryContainerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

using FluentAssertions;
using OpenSearch.Client;
using OpenSearch.OpenSearch.Xunit.XunitPlumbing;
using Xunit;

namespace Tests.QueryDsl.Container
{
public class QueryContainerTests
{
[TU]
[InlineData(false, false)]
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
public void StrictAndVerbatimAttributesAreRecursivelySetCorrectly(bool targetStrict, bool targetVerbatim)
{
// Arrange
var query0 = new TermQuery { Field = "field", Value = 1, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query1 = new BoolQuery { MustNot = new QueryContainer[] { query0 }, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query2 = new TermQuery { Field = "field2", Value = 7, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query3 = new BoolQuery { Must = new QueryContainer[] { query1, query2 }, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var queryContainer = new QueryContainer(query3);

// Act
queryContainer.Strict(targetStrict, recurse: true);
queryContainer.Verbatim(targetVerbatim, recurse: true);

// Assert
query0.IsStrict.Should().Be(targetStrict);
query0.IsVerbatim.Should().Be(targetVerbatim);
query1.IsStrict.Should().Be(targetStrict);
query1.IsVerbatim.Should().Be(targetVerbatim);
query2.IsStrict.Should().Be(targetStrict);
query2.IsVerbatim.Should().Be(targetVerbatim);
query3.IsStrict.Should().Be(targetStrict);
query3.IsVerbatim.Should().Be(targetVerbatim);
}

[TU]
[InlineData(false, false)]
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
public void StrictAndVerbatimAttributesAreSetCorrectly(bool targetStrict, bool targetVerbatim)
{
// Arrange
var query0 = new TermQuery { Field = "field", Value = 1, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query1 = new BoolQuery { MustNot = new QueryContainer[] { query0 }, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query2 = new TermQuery { Field = "field2", Value = 7, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var query3 = new BoolQuery { Must = new QueryContainer[] { query1, query2 }, IsStrict = !targetStrict, IsVerbatim = !targetVerbatim };
var queryContainer = new QueryContainer(query3);

// Act
queryContainer.Strict(targetStrict, recurse: false);
queryContainer.Verbatim(targetVerbatim, recurse: false);

// Assert
query0.IsStrict.Should().Be(!targetStrict);
query0.IsVerbatim.Should().Be(!targetVerbatim);
query1.IsStrict.Should().Be(!targetStrict);
query1.IsVerbatim.Should().Be(!targetVerbatim);
query2.IsStrict.Should().Be(!targetStrict);
query2.IsVerbatim.Should().Be(!targetVerbatim);

query3.IsStrict.Should().Be(targetStrict);
query3.IsVerbatim.Should().Be(targetVerbatim);
}

[TU]
[InlineData("name1")]
[InlineData("a name")]
[InlineData(null)]
public void SettingTheNameOnTheQueryContainerSetTheNameOnTheContainedQuery(string name)
{
// Arrange
var query0 = new TermQuery { Name = "a", Field = "field", Value = 1 };
var query1 = new BoolQuery { Name = "b", MustNot = new QueryContainer[] { query0 } };
var query2 = new TermQuery { Name = "c", Field = "field2", Value = 7 };
var query3 = new BoolQuery { Name = "d", Must = new QueryContainer[] { query1, query2 } };
var queryContainer = new QueryContainer(query3);

// Act
queryContainer.Name(name);

// Assert
query3.Name.Should().Be(name);
queryContainer.ContainedQuery.Name.Should().Be(name);
query0.Name.Should().Be("a");
query1.Name.Should().Be("b");
query2.Name.Should().Be("c");
}


}
}

0 comments on commit 08ce783

Please sign in to comment.