Esempio n. 1
0
        private ReadResult Reduce(IDictionary <long, SortedList <long, byte> > query, ReadSession readSession, int skip, int take)
        {
            IDictionary <long, BOCHit> scored = new Dictionary <long, BOCHit>();

            foreach (var term in query)
            {
                var hit = Scan(term.Key, term.Value);

                BOCHit score;

                if (scored.TryGetValue(hit.PostingsOffsets.PostingsOffset, out score))
                {
                    scored[hit.Key].Score = score.Score + hit.Value.Score;
                }
                else
                {
                    scored.Add(hit.Key, hit.Value);
                }
            }

            var sortedHits = scored.Values.OrderByDescending(h => h.Score);
            var offsets    = sortedHits.Select(h => h.PostingsOffset).ToArray();
            var docIds     = _postingsReader.Read(skip, take, offsets);
            var window     = docIds.GroupBy(x => x).Select(x => (x.Key, x.Count()))
                             .OrderByDescending(x => x.Item2)
                             .Skip(skip)
                             .Take(take)
                             .Select(x => x.Key).ToList();
            var docs = readSession.ReadDocs(window);

            return(new ReadResult {
                Docs = docs, Total = docIds.Count
            });
        }
Esempio n. 2
0
        private async Task <IDictionary <ulong, float> > DoRead(Query query)
        {
            try
            {
                IDictionary <ulong, float> result = null;

                var cursor = query;

                while (cursor != null)
                {
                    var keyHash = cursor.Term.Key.ToString().ToHash();
                    var ix      = GetIndex(keyHash);

                    if (ix != null)
                    {
                        var queryTerm = new VectorNode(cursor.Term.Value.ToString());

                        var match = ix.ClosestMatch(queryTerm);

                        if (match.Score > 0)
                        {
                            if (match.Node.PostingsOffset < 0)
                            {
                                throw new InvalidDataException();
                            }

                            var docIds = (await _postingsReader.Read(CollectionId, match.Node.PostingsOffset))
                                         .ToDictionary(x => x, y => match.Score);

                            if (result == null)
                            {
                                result = docIds;
                            }
                            else
                            {
                                if (cursor.And)
                                {
                                    var aggregatedResult = new Dictionary <ulong, float>();

                                    foreach (var doc in result)
                                    {
                                        float score;

                                        if (docIds.TryGetValue(doc.Key, out score))
                                        {
                                            aggregatedResult[doc.Key] = score + doc.Value;
                                        }
                                    }

                                    result = aggregatedResult;
                                }
                                else if (cursor.Not)
                                {
                                    foreach (var id in docIds.Keys)
                                    {
                                        result.Remove(id);
                                    }
                                }
                                else // Or
                                {
                                    foreach (var id in docIds)
                                    {
                                        float score;

                                        if (result.TryGetValue(id.Key, out score))
                                        {
                                            result[id.Key] = score + id.Value;
                                        }
                                        else
                                        {
                                            result.Add(id.Key, id.Value);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    cursor = cursor.Next;
                }
                _log.Log("query {0} matched {1} docs", query.Term, result == null ? 0 : result.Count);

                return(result);
            }
            catch (Exception ex)
            {
                _log.Log(ex);
                throw;
            }
        }