示例#1
0
        public IEnumerable <DocumentScore> Reduce()
        {
            var first = Scored;

            if (_queries != null)
            {
                foreach (var child in _queries)
                {
                    var other = child.Reduce();

                    if (child.And)
                    {
                        first = DocumentScore.CombineAnd(first, other).ToList();
                    }
                    else if (child.Not)
                    {
                        first = DocumentScore.Not(first, other).ToList();
                    }
                    else // Or
                    {
                        first = DocumentScore.CombineOr(first, other).ToList();
                    }
                }
            }

            return(first);
        }
示例#2
0
        public static IList <DocumentScore> Reduce(this IList <QueryContext> query)
        {
            var first = query[0].Scores;

            for (int i = 1; i < query.Count; i++)
            {
                var term  = query[i];
                var other = term.Scores;

                if (term.Query.Or)
                {
                    first = DocumentScore.CombineOr(first, other);
                }
                else if (term.Query.Not)
                {
                    first = DocumentScore.Not(first, other);
                }
                else // And
                {
                    first = DocumentScore.CombineAnd(first, other);
                }
            }

            return(first);
        }
示例#3
0
        public IEnumerable <DocumentScore> Reduce()
        {
            var first = Scored.ToList();

            foreach (var child in Children)
            {
                var other = child.Reduce().ToList();

                if (child.And)
                {
                    first = DocumentScore.CombineAnd(first, other).ToList();
                }
                else if (child.Not)
                {
                    var dic = first.ToDictionary(x => x.DocumentId);
                    foreach (var posting in other)
                    {
                        DocumentScore exists;
                        if (dic.TryGetValue(posting.DocumentId, out exists))
                        {
                            first.Remove(exists);
                        }
                    }
                }
                else // Or
                {
                    first = DocumentScore.CombineOr(first, other).ToList();
                }
            }

            return(first);
        }
示例#4
0
        public void Add(DocumentScore score)
        {
            if (!score.DocumentId.Equals(DocumentId))
            {
                throw new ArgumentException("Document IDs differ. Cannot combine.", "score");
            }

            Score = (Score + score.Score);
        }
示例#5
0
        public void Join(DocumentScore score)
        {
            if (!score.DocumentId.Equals(DocumentId))
            {
                throw new ArgumentException("Document IDs differ. Cannot add.", "score");
            }

            Score += score.Score;
        }
示例#6
0
        public static DocumentScore TakeLatestVersion(DocumentScore first, DocumentScore second)
        {
            if (!first.DocHash.Equals(second.DocHash))
            {
                throw new ArgumentException("Document hashes differ. Cannot take latest version.", "score");
            }

            if (first.Ix.VersionId > second.Ix.VersionId)
            {
                return(first);
            }
            return(second);
        }
示例#7
0
        private IList <DocumentScore> Score(IList <IList <DocumentPosting> > postings)
        {
            if (postings.Count == 1)
            {
                return(Score(postings[0]));
            }

            var weights = new DocumentScore[postings[0].Count][];

            SetWeights(postings, weights);

            var timer = Stopwatch.StartNew();

            var scoreDic = new Dictionary <int, DocumentScore>();

            foreach (DocumentScore[] score in weights)
            {
                if (score != null)
                {
                    DocumentScore sum = score[0];

                    if (sum == null)
                    {
                        continue;
                    }

                    for (int i = 1; i < score.Length; i++)
                    {
                        var s = score[i];
                        if (s == null)
                        {
                            sum = null;
                            break;
                        }
                        sum.Add(s);
                    }
                    if (sum != null)
                    {
                        DocumentScore existing;
                        if (scoreDic.TryGetValue(sum.DocumentId, out existing))
                        {
                            if (sum.Score > existing.Score)
                            {
                                scoreDic[sum.DocumentId] = sum;
                            }
                        }
                        else
                        {
                            scoreDic[sum.DocumentId] = sum;
                        }
                    }
                }
            }

            Log.DebugFormat("scored weights in {0}", timer.Elapsed);

            var notObsolete = new List <DocumentScore>();

            foreach (var score in scoreDic.Values)
            {
                var docHash = Session.ReadDocHash(score.DocumentId);

                if (!docHash.IsObsolete)
                {
                    score.DocHash = docHash.Hash;
                    notObsolete.Add(score);
                }
            }
            return(notObsolete);
        }
示例#8
0
        private int Score(
            DocumentScore[][] weights, ref IList <DocumentPosting> list1,
            IList <DocumentPosting> list2, int maxDistance, int numOfPasses, int passIndex)
        {
            var count   = 0;
            var cursor1 = 0;
            var cursor2 = 0;

            while (cursor1 < list1.Count && cursor2 < list2.Count)
            {
                var p1 = list1[cursor1];
                var p2 = list2[cursor2];

                if (p2.DocumentId > p1.DocumentId)
                {
                    cursor1++;
                    continue;
                }
                else if (p1.DocumentId > p2.DocumentId)
                {
                    cursor2++;
                    continue;
                }

                int distance    = p1.Data - p2.Data;
                int absDistance = Math.Abs(distance);

                //    Log.DebugFormat("pass {0}: d of {1}:{2} and {3}:{4} = {5}",
                //            passIndex, p1.DocumentId, p1.Data, p2.DocumentId, p2.Data, distance);

                if (absDistance <= maxDistance)
                {
                    var score = (double)1 / absDistance;

                    if (distance < 0)
                    {
                        score -= Math.Log(absDistance);
                    }

                    var documentScore = new DocumentScore(p1.DocumentId, score, Session.Version);

                    if (weights[cursor1] == null)
                    {
                        weights[cursor1]            = new DocumentScore[numOfPasses];
                        weights[cursor1][passIndex] = documentScore;
                    }
                    else
                    {
                        if (weights[cursor1][passIndex] == null ||
                            weights[cursor1][passIndex].Score < score)
                        {
                            weights[cursor1][passIndex] = documentScore;
                        }
                    }

                    //Log.DebugFormat("{0}:{1}:{2} scored {3}, distance {4}",
                    //    passIndex, p1.DocumentId, p1.Data, score, distance);

                    count++;

                    if (absDistance == 1)
                    {
                        cursor1++;
                        continue;
                    }
                }
                else if (distance < 0)
                {
                    cursor1++;
                    continue;
                }

                cursor2++;
            }

            return(count);
        }