public static QueryContainer CreateReturnQuery(Action<QueryContainer, BoolBaseQueryDescriptor> modify = null) { var returnQuery = new QueryContainer(); var returnBoolQuery = new BoolBaseQueryDescriptor() { }; ((IQueryContainer)returnQuery).Bool = returnBoolQuery; if (modify != null) { modify(returnQuery, returnBoolQuery); } return returnQuery; }
private static QueryContainer StrictSingleSideAndMerge(QueryContainer targetQuery, QueryContainer mergeQuery) { //if the target is not strict return if (!((IQueryContainer)targetQuery).IsStrict) return null; var mergeBoolQuery = ((IQueryContainer)mergeQuery).Bool; return CreateReturnQuery((returnQuery, returnBoolQuery) => { if (((IBoolQuery)mergeBoolQuery).MustNot.HasAny()) { ((IBoolQuery)returnBoolQuery).MustNot = ((IBoolQuery)mergeBoolQuery).MustNot; ((IBoolQuery)mergeBoolQuery).MustNot = null; } ((IBoolQuery)returnBoolQuery).Must = new[] { targetQuery }.Concat(((IBoolQuery)mergeBoolQuery).Must ?? Empty); }); }
private static QueryContainer SingleSideAndMerge(QueryContainer targetQuery, QueryContainer mergeQuery) { var targetBoolQuery = ((IQueryContainer)targetQuery).Bool; var mergeBoolQuery = ((IQueryContainer)mergeQuery).Bool; if (targetBoolQuery == null) return null; var combined = new[] { targetQuery, mergeQuery }; return CreateReturnQuery((returnQuery, returnBoolQuery) => { if (!targetBoolQuery.CanMergeMustAndMustNots() || !mergeBoolQuery.CanMergeMustAndMustNots()) { ((IBoolQuery)returnBoolQuery).Must = combined; return; } ((IBoolQuery)returnBoolQuery).Must = (((IBoolQuery)targetBoolQuery).Must ?? Empty) .Concat(mergeBoolQuery != null ? (((IBoolQuery)mergeBoolQuery).Must ?? Empty) : new[] { mergeQuery }) .NullIfEmpty(); ((IBoolQuery)returnBoolQuery).MustNot = (((IBoolQuery)targetBoolQuery).MustNot ?? Empty) .Concat(mergeBoolQuery != null ? (((IBoolQuery)mergeBoolQuery).MustNot ?? Empty) : Empty ).NullIfEmpty(); }); }
private static QueryContainer CombineIfNoMergeIsNecessary( QueryContainer leftQuery, QueryContainer rightQuery, QueryContainer[] combined) { var leftBoolQuery = ((IQueryContainer)leftQuery).Bool; var rightBoolQuery = ((IQueryContainer)rightQuery).Bool; //if neither side is already a boolquery // or if all boolqueries are strict. // or if one side is strict and the other is null var mergeLeft = !((IQueryContainer)leftQuery).IsStrict && (leftBoolQuery == null || ((IBoolQuery)leftBoolQuery).MinimumShouldMatch == null); var mergeRight = !((IQueryContainer)rightQuery).IsStrict && (rightBoolQuery == null || ((IBoolQuery)rightBoolQuery).MinimumShouldMatch == null); //no merging is needed just return the combination if ( (leftBoolQuery == null && rightBoolQuery == null) || (!mergeLeft && !mergeRight) || (((IQueryContainer)leftQuery).IsStrict && rightBoolQuery == null) || (((IQueryContainer)rightQuery).IsStrict && leftBoolQuery == null) ) { return CreateReturnQuery((returnQuery, returnBoolQuery) => ((IBoolQuery)returnBoolQuery).Must = combined); } return null; }
private static void JoinShouldOnSide(QueryContainer lbq, QueryContainer rbq, BoolBaseQueryDescriptor bq) { ((IBoolQuery)bq).Should = lbq.MergeShouldQueries(rbq); }
public static QueryContainer operator !(QueryContainer lbq) { if (lbq == null || ((IQueryContainer)lbq).IsConditionless) { var newConditionless = new QueryContainer(); ((IQueryContainer)newConditionless).IsConditionless = true; return newConditionless; } var f = new QueryContainer(); var fq = new BoolBaseQueryDescriptor(); ((IBoolQuery)fq).MustNot = new[] { lbq }; ((IQueryContainer)f).Bool = fq; return f; }
public static QueryContainer operator |(QueryContainer leftQuery, QueryContainer rightQuery) { var defaultQuery = new QueryContainer(); ((IQueryContainer)defaultQuery).IsConditionless = true; leftQuery = leftQuery ?? defaultQuery; rightQuery = rightQuery ?? defaultQuery; var combined = new[] { leftQuery, rightQuery }; if (combined.Any(bf => ((IQueryContainer)bf).IsConditionless)) return combined.FirstOrDefault(bf => !((IQueryContainer)bf).IsConditionless) ?? defaultQuery; var leftBoolQuery = ((IQueryContainer)leftQuery).Bool; var rightBoolQuery = ((IQueryContainer)rightQuery).Bool; var f = new QueryContainer(); var fq = new BoolBaseQueryDescriptor(); ((IBoolQuery)fq).Should = new[] { leftQuery, rightQuery }; ((IQueryContainer)f).Bool = fq; var mergeLeft = !((IQueryContainer)leftQuery).IsStrict && (leftBoolQuery == null || ((IBoolQuery)leftBoolQuery).MinimumShouldMatch == null); var mergeRight = !((IQueryContainer)rightQuery).IsStrict && (rightBoolQuery == null || ((IBoolQuery)rightBoolQuery).MinimumShouldMatch == null); //if neither the left nor the right side represent a bool query join them if (((IQueryContainer)leftQuery).Bool == null && ((IQueryContainer)rightQuery).Bool == null) { ((IBoolQuery)fq).Should = leftQuery.MergeShouldQueries(rightQuery); return f; } //if the left or right sight already is a bool query join the non bool query side of the //of the operation onto the other. if (((IQueryContainer)leftQuery).Bool != null && ((IQueryContainer)rightQuery).Bool == null && mergeLeft) { JoinShouldOnSide(leftQuery, rightQuery, fq); } else if (((IQueryContainer)rightQuery).Bool != null && ((IQueryContainer)leftQuery).Bool == null && mergeRight) { JoinShouldOnSide(rightQuery, leftQuery, fq); } //both sides already represent a bool query else { //both sides report that we may merge the shoulds if (mergeLeft && mergeRight && leftBoolQuery.CanJoinShould() && rightBoolQuery.CanJoinShould()) ((IBoolQuery)fq).Should = leftQuery.MergeShouldQueries(rightQuery); else //create a new nested bool with two separate should bool sections ((IBoolQuery)fq).Should = new[] { leftQuery, rightQuery }; } return f; }
/// <summary> /// AND's two BaseQueries /// </summary> /// <returns>A new basequery that represents the AND of the two</returns> public static QueryContainer operator &(QueryContainer leftQuery, QueryContainer rightQuery) { var defaultQuery = new QueryContainer(); ((IQueryContainer)defaultQuery).IsConditionless = true; leftQuery = leftQuery ?? defaultQuery; rightQuery = rightQuery ?? defaultQuery; var combined = new[] { leftQuery, rightQuery }; //if any of the queries is conditionless return the first one that is not //or return the defaultQuery if (combined.Any(bf => ((IQueryContainer)bf).IsConditionless)) return combined.FirstOrDefault(bf => !((IQueryContainer)bf).IsConditionless) ?? defaultQuery; //return simple combination of the two if merging is not possible/necessary var noMergeQuery = CombineIfNoMergeIsNecessary(leftQuery, rightQuery, combined); if (noMergeQuery != null) return noMergeQuery; //if the left is a strict bool try to merge right on left first var joinStrictLeft = StrictSingleSideAndMerge(leftQuery, rightQuery); if (joinStrictLeft != null) return joinStrictLeft; // if the right side is a strict bool try to merge left on right var joinStrictRight = StrictSingleSideAndMerge(rightQuery, leftQuery); if (joinStrictRight != null) return joinStrictRight; // if the left side is a normal bool try to merge right on left var joinLeft = SingleSideAndMerge(leftQuery, rightQuery); if (joinLeft != null) return joinLeft; // if the right side is a normal bool try to merge lefft on right var joinRight = SingleSideAndMerge(rightQuery, leftQuery); return joinRight ?? defaultQuery; }