Beispiel #1
0
        public IEnumerable <QueryWordMatch> Apply(IntermediateQueryResult left, IntermediateQueryResult right)
        {
            // TODO Verify this assumption - forcing RIGHT to contain more will cause a bigger dictionary to be built
            // Swap over the variables to ensure we're performing as few iterations as possible in the intersection
            // "left" and "right" have no special meaning when performing an intersection
            var rightDictionary = right.Matches.ToDictionary(i => i.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightDictionary.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    // Exists in both
                    yield return(new QueryWordMatch(
                                     leftMatch.ItemId,
                                     MergeFields(leftMatch, rightMatch)));

                    rightDictionary.Remove(leftMatch.ItemId);
                }
                else
                {
                    // Exists only in current
                    yield return(new QueryWordMatch(leftMatch.ItemId, leftMatch.FieldMatches));
                }
            }

            // Any items still remaining in nextDictionary exist only in the new results so can just be yielded
            foreach (var rightMatch in rightDictionary.Values)
            {
                yield return(new QueryWordMatch(rightMatch.ItemId, rightMatch.FieldMatches));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Applies the union operation to the <see cref="IntermediateQueryResult"/> instances.
        /// </summary>
        public static IEnumerable <ScoredToken> Apply(IntermediateQueryResult left, IntermediateQueryResult right)
        {
            // Swap over the variables to ensure we're performing as few iterations as possible in the intersection
            // "left" and "right" have no special meaning when performing an intersection
            var rightDictionary = right.Matches.ToDictionary(i => i.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightDictionary.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    // Exists in both
                    yield return(new ScoredToken(
                                     leftMatch.ItemId,
                                     MergeFields(leftMatch, rightMatch).ToList()));

                    rightDictionary.Remove(leftMatch.ItemId);
                }
                else
                {
                    // Exists only in current
                    yield return(leftMatch);
                }
            }

            // Any items still remaining in nextDictionary exist only in the new results so can just be yielded
            foreach (var rightMatch in rightDictionary.Values)
            {
                yield return(rightMatch);
            }
        }
        public IEnumerable <QueryWordMatch> Apply(IntermediateQueryResult left, IntermediateQueryResult right, int leftTolerance, int rightTolerance)
        {
            // TODO Verify this assumption - forcing RIGHT to contain more will cause a bigger dictionary to be built
            // Swap over the variables to ensure we're performing as few iterations as possible in the intersection
            // "left" and "right" have no special meaning when performing an intersection
            SwapIf(left.Matches.Count > right.Matches.Count, ref left, ref right);

            var rightItems = right.Matches.ToDictionary(m => m.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightItems.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    var positionalMatches = PositionallyMatchAndCombineWords(
                        leftMatch.FieldMatches,
                        rightMatch.FieldMatches,
                        leftTolerance,
                        rightTolerance);

                    if (positionalMatches.Count > 0)
                    {
                        yield return(new QueryWordMatch(leftMatch.ItemId, positionalMatches));
                    }
                }
            }
        }
        /// <summary>
        /// Applies the intersection logic.
        /// </summary>
        public static IEnumerable <ScoredToken> Apply(IntermediateQueryResult left, IntermediateQueryResult right)
        {
            // Swap over the variables to ensure we're performing as few iterations as possible in the intersection
            // "left" and "right" have no special meaning when performing an intersection
            var swapLeftAndRight = left.Matches.Count > right.Matches.Count;

            SwapIf(swapLeftAndRight, ref left, ref right);

            var rightItems = right.Matches.ToDictionary(m => m.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightItems.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    var positionalMatches = EnumerateFieldMatches(
                        (swapLeftAndRight ? rightMatch : leftMatch).FieldMatches,
                        (swapLeftAndRight ? leftMatch : rightMatch).FieldMatches);

                    if (positionalMatches.Count > 0)
                    {
                        yield return(new ScoredToken(leftMatch.ItemId, positionalMatches));
                    }
                }
            }
        }
        /// <summary>
        /// Applies the intersection to the <see cref="IntermediateQueryResult"/> instances.
        /// </summary>
        public static IEnumerable <ScoredToken> Apply(IntermediateQueryResult left, IntermediateQueryResult right, int leftTolerance, int rightTolerance)
        {
            // Swap over the variables to ensure we're performing as few iterations as possible in the intersection
            // Also swap the tolerance values around, otherwise we reverse the tolerance directionality.
            var swapLeftAndRight = left.Matches.Count > right.Matches.Count;

            SwapIf(swapLeftAndRight, ref left, ref right);
            SwapIf(swapLeftAndRight, ref leftTolerance, ref rightTolerance);

            var rightItems = right.Matches.ToDictionary(m => m.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightItems.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    var positionalMatches = PositionallyMatchAndCombineTokens(
                        swapLeftAndRight,
                        leftMatch.FieldMatches,
                        rightMatch.FieldMatches,
                        leftTolerance,
                        rightTolerance);

                    if (positionalMatches.Count > 0)
                    {
                        yield return(new ScoredToken(leftMatch.ItemId, positionalMatches));
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Applies the intersection to the two <see cref="IntermediateQueryResult"/>s.
        /// </summary>
        public static IEnumerable <ScoredToken> Apply(IntermediateQueryResult left, IntermediateQueryResult right)
        {
            // Swap over left and right to ensure we're performing as few iterations as possible in the intersection
            // The trade-off here is that we're building a larger dictionary
            SwapIf(left.Matches.Count > right.Matches.Count, ref left, ref right);

            var rightItems = right.Matches.ToDictionary(m => m.ItemId);

            foreach (var leftMatch in left.Matches)
            {
                if (rightItems.TryGetValue(leftMatch.ItemId, out var rightMatch))
                {
                    yield return(new ScoredToken(
                                     leftMatch.ItemId,
                                     MergeFields(leftMatch, rightMatch).ToList()));
                }
            }
        }
 /// <summary>
 /// Union this and the specified instance - this is the equivalent of an OR statement.
 /// </summary>
 public IntermediateQueryResult Union(IntermediateQueryResult results)
 {
     return(new IntermediateQueryResult(UnionMerger.Apply(this, results)));
 }
 /// <summary>
 /// Intersects this and the specified instance - this is the equivalent of an AND statement.
 /// </summary>
 public IntermediateQueryResult Intersect(IntermediateQueryResult results)
 {
     return(new IntermediateQueryResult(IntersectMerger.Apply(this, results)));
 }
 /// <summary>
 /// Intersects this and the specified instance, but only when the positions of the matched tokens are within a given tolerance. Matching tokens are combined
 /// into <see cref="CompositeTokenMatchLocation"/> instances.
 /// </summary>
 public IntermediateQueryResult CompositePositionalIntersect(IntermediateQueryResult results, int leftTolerance, int rightTolerance)
 {
     return(new IntermediateQueryResult(CompositePositionalIntersectMerger.Apply(this, results, leftTolerance, rightTolerance)));
 }
Beispiel #10
0
 /// <summary>
 /// Intersects this and the specified instance, but only when the positions of the matched words on the left are preceding the words on the right.
 /// </summary>
 public IntermediateQueryResult PrecedingIntersect(IntermediateQueryResult results)
 {
     return(new IntermediateQueryResult(PrecedingIntersectMerger.Instance.Apply(this, results)));
 }