Пример #1
0
 //读取doc文档
 public static IEnumerable <T> ReadModels <T>(Searcher indexSearcher, TopDocs topDocs, string returnFields = null)
     where T : class, new()
 {
     if (topDocs.TotalHits == 0)
     {
         yield break;
     }
     foreach (var scoreDoc in topDocs.ScoreDocs)
     {
         Document doc;
         if (returnFields == null)
         {
             doc = indexSearcher.Doc(scoreDoc.Doc);
         }
         else
         {
             string[]         fieldArr = returnFields.Split(',');
             MapFieldSelector field    = new MapFieldSelector(fieldArr);//指定返回列
             doc = indexSearcher.Doc(scoreDoc.Doc, field);
         }
         yield return(LuceneTool.CreateModel <T>(doc));
     }
 }
Пример #2
0
    //读取doc文档
    public static IEnumerable <T> ReadModels <T>(Searcher indexSearcher, TopDocs topDocs, int skip, string returnFields = null)
        where T : class, new()
    {
        if (skip >= topDocs.TotalHits)
        {
            yield break;
        }

        for (int i = skip; i < topDocs.ScoreDocs.Length; i++)
        {
            Document doc;
            if (returnFields == null)
            {
                doc = indexSearcher.Doc(topDocs.ScoreDocs[i].Doc);
            }
            else
            {
                string[]         fieldArr = returnFields.Split(',');
                MapFieldSelector field    = new MapFieldSelector(fieldArr);//指定返回列
                doc = indexSearcher.Doc(topDocs.ScoreDocs[i].Doc, field);
            }
            yield return(LuceneTool.CreateModel <T>(doc));
        }
    }
        /// <summary>
        /// Supplied with the result of a Lucene query, this method will yield a constructed LookMatch for each in order
        /// </summary>
        /// <param name="searcherName"></param>
        /// <param name="indexSearcher">The searcher supplied to get the Lucene doc for each id in the Lucene results (topDocs)</param>
        /// <param name="topDocs">The results of the Lucene query (a collection of ids in an order)</param>
        /// <param name="requestFields">Enum value specifying which Lucene fields shoudl be returned</param>
        /// <param name="getHighlight">Function used to get the highlight text for a given result text</param>
        /// <param name="getDistance">Function used to calculate distance (if a location was supplied in the original query)</param>
        /// <returns></returns>
        internal static IEnumerable <LookMatch> GetLookMatches(
            string searcherName,
            IndexSearcher indexSearcher,
            ScoreDoc[] scoreDocs,
            RequestFields requestFields,
            Func <string, IHtmlString> getHighlight,
            Func <int, double?> getDistance)
        {
            MapFieldSelector mapFieldSelector = null; // when null, all fields are returned

            // these fields are always requested
            var lookFieldNames = new string[] {
                LookConstants.NodeIdField,
                LookConstants.NodeKeyField,
                LookConstants.NodeTypeField,
                LookConstants.NodeAliasField,
                LookConstants.HostIdField,
                LookConstants.NameField,
                LookConstants.DateField,
                LookConstants.TextField,
                LookConstants.AllTagsField,
                LookConstants.LocationField
            };

            if (requestFields == RequestFields.LookFieldsOnly)
            {
                // limit fields to be returned
                mapFieldSelector = new MapFieldSelector(lookFieldNames);
            }

            var getHostId = new Func <string, int?>(x => {
                if (int.TryParse(x, out int id))
                {
                    return(id);
                }
                return(null);
            });

            var getItemGuid = new Func <string, Guid?>(x =>
            {
                if (Guid.TryParse(x, out Guid guid))
                {
                    return(guid);
                }
                return(null);
            });

            var getCultureInfo = new Func <string, CultureInfo>(x =>
            {
                if (int.TryParse(x, out int lcid))
                {
                    return(new CultureInfo(lcid));
                }
                return(null);
            });

            // there should always be a valid node type value to parse
            var getNodeType = new Func <string, PublishedItemType>(x =>
            {
                Enum.TryParse(x, out PublishedItemType type); return(type);
            });

            // helper to simplify call below
            var getTags = new Func <Field[], LookTag[]>(x => {
                if (x != null)
                {
                    return(x.Select(y => new LookTag(y.StringValue())).ToArray());
                }
                return(new LookTag[] { });
            });

            foreach (var scoreDoc in scoreDocs)
            {
                var docId = scoreDoc.doc;

                var doc = indexSearcher.Doc(docId, mapFieldSelector);

                var lookMatch = new LookMatch(
                    searcherName,
                    scoreDoc.doc,
                    scoreDoc.score,
                    getHostId(doc.Get(LookConstants.HostIdField)),    // could be null
                    Convert.ToInt32(doc.Get(LookConstants.NodeIdField)),
                    getItemGuid(doc.Get(LookConstants.NodeKeyField)), // this should only be null for unit tests (outside umbraco context)
                    doc.Get(LookConstants.NodeAliasField),
                    getCultureInfo(doc.Get(LookConstants.CultureField)),
                    doc.Get(LookConstants.NameField),
                    doc.Get(LookConstants.DateField).LuceneStringToDate(),
                    doc.Get(LookConstants.TextField),
                    getHighlight(doc.Get(LookConstants.TextField)),
                    getTags(doc.GetFields(LookConstants.AllTagsField)),
                    doc.Get(LookConstants.LocationField) != null ? Location.FromString(doc.Get(LookConstants.LocationField)) : null,
                    getDistance(docId),
                    getNodeType(doc.Get(LookConstants.NodeTypeField)),
                    LookService.Instance._umbracoHelper
                    );

                // populate the Examine SearchResult.Fields collection
                if (requestFields == RequestFields.AllFields)
                {
                    string[] fieldNames = doc
                                          .GetFields()
                                          .Cast <Field>()
                                          .Select(x => x.Name())
                                          .ToArray();

                    foreach (var fieldName in fieldNames)
                    {
                        var values = doc.GetValues(fieldName);

                        // replicating logic from Examine
                        if (values.Length > 1)
                        {
                            // TODO: reflection to set internal MultiValueFields

                            lookMatch.Fields[fieldName] = values[0];
                        }
                        else if (values.Length > 0)
                        {
                            lookMatch.Fields[fieldName] = values[0];
                        }
                    }
                }
                else
                {
                    // look fields only

                    // TODO: map fields
                }

                yield return(lookMatch);
            }
        }
Пример #4
0
        public IEnumerable <IRow> Read()
        {
            var reader   = _readerFactory.Create();
            var numDocs  = reader.NumDocs();
            var selector = new MapFieldSelector(_fields.Select(f => f.Name).ToArray());

            using (var searcher = _searcherFactory.Create()) {
                // read from input?  consider filters, and field names
                if (_readFrom == ReadFrom.Input)
                {
                    if (_context.Entity.Filter.Any())
                    {
                        var queryFields = _context.Entity.Filter.Select(f => f.Field).ToArray();
                        var query       = string.Join(" ", _context.Entity.Filter.Select(f => "(" + (string.IsNullOrEmpty(f.Expression) ? f.Field + ":" + f.Value : f.Expression) + ") " + f.Continuation.ToUpper()));
                        query = query.Remove(query.Length - 3);
                        var topFieldCollector = TopFieldCollector.Create(Sort.INDEXORDER, numDocs, false, false, false, false);

                        searcher.Search(new MultiFieldQueryParser(V, queryFields, _analyzer).Parse(query), topFieldCollector);

                        var topDocs = topFieldCollector.TopDocs();

                        if (topDocs == null)
                        {
                            yield break;
                        }

                        for (var i = 0; i < topDocs.TotalHits; i++)
                        {
                            var row = _rowFactory.Create();
                            var doc = searcher.Doc(i, selector);
                            foreach (var field in _fields)
                            {
                                row[field] = field.Convert(doc.Get(field.Name));
                            }
                            yield return(row);
                        }
                    }
                    else
                    {
                        for (var i = 0; i < numDocs; i++)
                        {
                            if (reader.IsDeleted(i))
                            {
                                continue;
                            }
                            var doc = reader.Document(i, selector);
                            var row = _rowFactory.Create();
                            foreach (var field in _fields)
                            {
                                row[field] = field.Convert(doc.Get(field.Name));
                            }
                            yield return(row);
                        }
                    }
                }
                else      // read from output? consider tfldeleted and field aliases

                {
                    var tflDeleted = _context.Entity.TflDeleted();
                    var collector  = TopFieldCollector.Create(Sort.INDEXORDER, numDocs, false, false, false, false);
                    searcher.Search(LuceneConversion.TypeSearch(tflDeleted, tflDeleted.Alias, false), collector);

                    var topDocs = collector.TopDocs();

                    if (topDocs == null)
                    {
                        yield break;
                    }

                    for (var i = 0; i < topDocs.TotalHits; i++)
                    {
                        var row = _rowFactory.Create();
                        var doc = searcher.Doc(i, selector);
                        foreach (var field in _fields)
                        {
                            row[field] = field.Convert(doc.Get(field.Alias));
                        }
                        yield return(row);
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="indexSearcher"></param>
        /// <param name="topDocs"></param>
        /// <param name="getHighlight"></param>
        /// <param name="getDistance"></param>
        /// <returns></returns>
        private static IEnumerable <LookMatch> GetLookMatches(
            LookQuery lookQuery,
            IndexSearcher indexSearcher,
            TopDocs topDocs,
            Func <string, IHtmlString> getHighlight,
            Func <int, double?> getDistance)
        {
            bool getText = lookQuery.TextQuery != null && lookQuery.TextQuery.GetText;
            bool getTags = lookQuery.TagQuery != null && lookQuery.TagQuery.GetTags;

            var fields = new List <string>();

            fields.Add(LuceneIndexer.IndexNodeIdFieldName); // "__NodeId"
            fields.Add(LookService.DateField);
            fields.Add(LookService.NameField);
            fields.Add(LookService.LocationField);

            /// if a highlight function is supplied, then it'll need the text field to process
            if (getHighlight != null || getText)
            {
                fields.Add(LookService.TextField);
            }

            if (getHighlight == null) // if highlight func doens't exist, then create one to always return null
            {
                getHighlight = x => null;
            }

            if (getTags)
            {
                fields.Add(LookService.TagsField);
            }

            var mapFieldSelector = new MapFieldSelector(fields.ToArray());

            foreach (var scoreDoc in topDocs.ScoreDocs)
            {
                var docId = scoreDoc.doc;

                var doc = indexSearcher.Doc(docId, mapFieldSelector);

                DateTime?date = null;

                if (long.TryParse(doc.Get(LookService.DateField), out long ticks))
                {
                    date = new DateTime(ticks);
                }

                var lookMatch = new LookMatch()
                {
                    Id        = Convert.ToInt32(doc.Get(LuceneIndexer.IndexNodeIdFieldName)),
                    Highlight = getHighlight(doc.Get(LookService.TextField)),
                    Text      = getText ? doc.Get(LookService.TextField) : null,
                    Tags      = getTags ? doc.Get(LookService.TagsField).Split(' ') : null,
                    Date      = date,
                    Name      = doc.Get(LookService.NameField),
                    Location  = doc.Get(LookService.LocationField) != null ? new Location(doc.Get(LookService.LocationField)) : null,
                    Distance  = getDistance(docId),
                    Score     = scoreDoc.score
                };

                yield return(lookMatch);
            }
        }