in src/Elastic.Clients.Elasticsearch/_Shared/Types/QueryDsl/BoolQueryAndExtensions.cs [53:134]
private static bool TryHandleUnmergableBools(Query leftContainer, Query rightContainer, BoolQuery? leftBool, BoolQuery? rightBool, [NotNullWhen(true)] out Query? query)
{
query = null;
var leftCantMergeAnd = leftBool is not null && !leftBool.CanMergeAnd();
var rightCantMergeAnd = rightBool is not null && !rightBool.CanMergeAnd();
if (!leftCantMergeAnd && !rightCantMergeAnd)
{
return false;
}
if (leftCantMergeAnd && rightCantMergeAnd)
{
query = CreateMustContainer(leftContainer, rightContainer);
}
// right can't merge but left can and is a bool so we add left to the must clause of right
else if (!leftCantMergeAnd && leftBool != null && rightCantMergeAnd)
{
if (rightContainer is null)
{
query = leftContainer;
}
else
{
// We create a copy here to avoid side-effects on a user provided bool query such as
// adding a must clause where one did not previously exist.
var leftBoolCopy = new BoolQuery
{
Boost = leftBool.Boost,
MinimumShouldMatch = leftBool.MinimumShouldMatch,
QueryName = leftBool.QueryName,
Should = leftBool.Should,
Must = leftBool.Must.AddIfNotNull(rightContainer).ToArray(),
MustNot = leftBool.MustNot,
Filter = leftBool.Filter
};
query = new Query { Bool = leftBoolCopy };
}
}
// right can't merge and left is not a bool, we forcefully create a wrapped must container
else if (!leftCantMergeAnd && leftBool is null && rightCantMergeAnd)
{
query = CreateMustContainer(leftContainer, rightContainer);
}
// left can't merge but right can and is a bool so we add left to the must clause of right
else if (leftCantMergeAnd && !rightCantMergeAnd && rightBool is not null)
{
if (leftContainer is null)
{
query = rightContainer;
}
else
{
var rightBoolCopy = new BoolQuery
{
Boost = rightBool.Boost,
MinimumShouldMatch = rightBool.MinimumShouldMatch,
QueryName = rightBool.QueryName,
Should = rightBool.Should,
Must = rightBool.Must.AddIfNotNull(leftContainer).ToArray(),
MustNot = rightBool.MustNot,
Filter = rightBool.Filter
};
query = new Query { Bool = rightBoolCopy };
}
}
//left can't merge and right is not a bool, we forcefully create a wrapped must container
else if (leftCantMergeAnd && !rightCantMergeAnd && rightBool == null)
{
query = CreateMustContainer(new List<Query> { leftContainer, rightContainer });
}
return query is not null;
}