Exemplo n.º 1
0
        public void CreateIndex(string name, FieldDefinitionCollection fields, Analyzer analyzer = null)
        {
            if (analyzer == null)
            {
                analyzer = new KeywordAnalyzer();
            }

            //  examineIndex.WaitForIndexQueueOnShutdown = false;
            _examineManager.TryGetIndex(name, out var index);
            if (index == null)
            {
                var dir = examineIndex.GetLuceneDirectory();

                if (!string.IsNullOrEmpty(dir.GetLockID()))
                {
                    //  _loggingService.Info("Forcing index {IndexerName} to be unlocked since it was left in a locked state", examineIndex.Name);

                    dir.ClearLock("write.lock");
                }

                if (IndexWriter.IsLocked(dir))
                {
                    IndexWriter.Unlock(dir);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Remove the media from the PDF index
        /// </summary>
        /// <param name="media"></param>
        public void RemoveFromIndex(params IMedia[] media)
        {
            if (!_examineManager.TryGetIndex(PdfIndexConstants.PdfIndexName, out var index))
            {
                return;
            }
            var ids = media.Select(m => m.Id.ToInvariantString());

            index.DeleteFromIndex(ids);
        }
Exemplo n.º 3
0
 public void ConfigureIndexes(IEnumerable<IIndexConfig> indexes)
 {
     foreach (var index in indexes)
     {
         if (_examineManager.TryGetIndex(index.Name, out IIndex existingIndex) == true)
         {
             throw new Exception($"Index {index.Name} already exists");
         }
     }
 }
Exemplo n.º 4
0
        private PagedResult <ProductPage> GetPagedProducts(int?collectionId, string category, int page, int pageSize)
        {
            if (_examineManager.TryGetIndex("ExternalIndex", out var index))
            {
                var searcher = index.GetSearcher();
                var query    = searcher.CreateQuery()
                               .Field("__NodeTypeAlias", ProductPage.ModelTypeAlias);

                if (collectionId.HasValue)
                {
                    query = query.And().Field("parentID", collectionId.Value);
                }

                if (!category.IsNullOrWhiteSpace())
                {
                    query = query.And().Field("categoryAliases", category);
                }

                var results      = query.OrderBy(new SortableField("name", SortType.String)).Execute(pageSize * page);
                var totalResults = results.TotalItemCount;
                var pagedResults = results.Skip(pageSize * (page - 1));

                var items = pagedResults.ToPublishedSearchResults(_umbracoContextAccessor.UmbracoContext.Content)
                            .Select(x => x.Content)
                            .OfType <ProductPage>();

                return(new PagedResult <ProductPage>(totalResults, page, pageSize)
                {
                    Items = items
                });
            }

            return(new PagedResult <ProductPage>(0, page, pageSize));
        }
Exemplo n.º 5
0
        private ISearcher GetSearchProviderSafe()
        {
            if (_searchProvider != null)
            {
                return(_searchProvider);
            }

            try
            {
                return(_examineManager.TryGetIndex(Constants.UmbracoIndexes.InternalIndexName, out var index) ? index.GetSearcher() : null);
            }
            catch (FileNotFoundException)
            {
                //Currently examine is throwing FileNotFound exceptions when we have a load balanced filestore and a node is published in umbraco
                //See this thread: http://examine.cdodeplex.com/discussions/264341
                //Catch the exception here for the time being, and just fallback to GetMedia
                // TODO: Need to fix examine in LB scenarios!
            }
            catch (NullReferenceException)
            {
                //This will occur when the search provider cannot be initialized. In newer examine versions the initialization is lazy and therefore
                // the manager will return the singleton without throwing initialization errors, however if examine isn't configured correctly a null
                // reference error will occur because the examine settings are null.
            }
            catch (ObjectDisposedException)
            {
                //If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot
                //be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db.
            }
            return(null);
        }
        public ActionResult Search(string q = "", int p = 1, int ps = 12)
        {
            // The logic for searching is mostly pulled from ezSearch
            // https://github.com/umco/umbraco-ezsearch/blob/master/Src/Our.Umbraco.ezSearch/Web/UI/Views/MacroPartials/ezSearch.cshtml

            var result = new PagedResult <IPublishedContent>(0, 1, ps);

            if (!q.IsNullOrWhiteSpace() && _examineManager.TryGetIndex("ExternalIndex", out var index))
            {
                var searchTerms  = Tokenize(q);
                var searchFields = new[] { "nodeName", "metaTitle", "description", "shortDescription", "longDescription", "metaDescription", "bodyText", "content" };

                var searcher = index.GetSearcher();
                var query    = new StringBuilder();

                query.Append("+__IndexType:content "); // Must be content
                query.Append("-templateID:0 ");        // Must have a template
                query.Append("-umbracoNaviHide:1 ");   // Must no be hidden

                // Ensure page contains all search terms in some way
                foreach (var term in searchTerms)
                {
                    var groupedOr = searchFields.Aggregate(new StringBuilder(), (innerQuery, searchField) =>
                    {
                        var format = searchField.Contains(" ") ? @"{0}:""{1}"" " : "{0}:{1}* ";
                        innerQuery.AppendFormat(format, searchField, term);
                        return(innerQuery);
                    });

                    query.Append("+(" + groupedOr.ToString() + ") ");
                }

                // Rank content based on positon of search terms in fields
                for (var i = 0; i < searchFields.Length; i++)
                {
                    foreach (var term in searchTerms)
                    {
                        var searchField = searchFields[i];
                        var format      = searchField.Contains(" ") ? @"{0}:""{1}""^{2} " : "{0}:{1}*^{2} ";
                        query.AppendFormat(format, searchField, term, searchFields.Length - i);
                    }
                }

                var examineQuery = searcher.CreateQuery().NativeQuery(query.ToString());
                var results      = examineQuery.Execute(ps * p);
                var totalResults = results.TotalItemCount;
                var pagedResults = results.Skip(ps * (p - 1));

                result = new PagedResult <IPublishedContent>(totalResults, p, ps)
                {
                    Items = pagedResults.Select(x => UmbracoContext.Content.GetById(int.Parse(x.Id)))
                };
            }

            return(PartialView("SearchResults", result));
        }
Exemplo n.º 7
0
        public void Initialize()
        {
            if (examineManager.TryGetIndex("ExternalIndex", out IIndex externalIndex))
            {
                externalIndex.FieldDefinitionCollection.AddOrUpdate(
                    new FieldDefinition("articleDate", FieldDefinitionTypes.Long));

                ((BaseIndexProvider)externalIndex).TransformingIndexValues +=
                    IndexerComponent_TransformingIndexValues;
            }
        }
Exemplo n.º 8
0
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args)
        {
            if (args.MessageType != MessageType.RefreshByPayload)
            {
                return;
            }

            if (!_fullTextConfig.IsFullTextIndexingEnabled())
            {
                _logger.Debug <UpdateCacheOnPublish>("FullTextIndexing is not enabled");
                return;
            }

            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                _logger.Error <UpdateCacheOnPublish>(new InvalidOperationException("No index found by name ExternalIndex"));
                return;
            }

            foreach (var payload in (ContentCacheRefresher.JsonPayload[])args.MessageObject)
            {
                if (payload.ChangeTypes.HasType(TreeChangeTypes.Remove))
                {
                    _cacheService.DeleteFromCache(payload.Id);
                }
                else if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
                {
                    // just ignore that payload (Umbracos examine implementation does the same)
                }
                else // RefreshNode or RefreshBranch (maybe trashed)
                {
                    _cacheService.AddCacheTask(payload.Id);

                    // branch
                    if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
                    {
                        const int pageSize = 500;
                        var       page     = 0;
                        var       total    = long.MaxValue;
                        while (page * pageSize < total)
                        {
                            var descendants = _contentService.GetPagedDescendants(payload.Id, page++, pageSize, out total,
                                                                                  //order by shallowest to deepest, this allows us to check it's published state without checking every item
                                                                                  ordering: Ordering.By("Path", Direction.Ascending));

                            foreach (var descendant in descendants)
                            {
                                _cacheService.AddCacheTask(descendant.Id);
                            }
                        }
                    }
                }
            }
        }
        private ActionResult ValidateSearcher(string searcherName, out ISearcher searcher)
        {
            //try to get the searcher from the indexes
            if (_examineManager.TryGetIndex(searcherName, out IIndex index))
            {
                searcher = index.Searcher;
                return(new OkResult());
            }

            //if we didn't find anything try to find it by an explicitly declared searcher
            if (_examineManager.TryGetSearcher(searcherName, out searcher))
            {
                return(new OkResult());
            }

            var response1 = new BadRequestObjectResult($"No searcher found with name = {searcherName}");

            HttpContext.SetReasonPhrase("Searcher Not Found");
            return(response1);
        }
        private HttpResponseMessage ValidateSearcher(string searcherName, out ISearcher searcher)
        {
            //try to get the searcher from the indexes
            if (_examineManager.TryGetIndex(searcherName, out var index))
            {
                searcher = index.GetSearcher();
                return(Request.CreateResponse(HttpStatusCode.OK));
            }

            //if we didn't find anything try to find it by an explicitly declared searcher
            if (_examineManager.TryGetSearcher(searcherName, out searcher))
            {
                return(Request.CreateResponse(HttpStatusCode.OK));
            }

            var response1 = Request.CreateResponse(HttpStatusCode.BadRequest);

            response1.Content      = new StringContent($"No searcher found with name = {searcherName}");
            response1.ReasonPhrase = "Searcher Not Found";
            return(response1);
        }
Exemplo n.º 11
0
            public void Initialize()
            {
                if (!_examineManager.TryGetIndex(UmbracoIndexes.ExternalIndexName, out IIndex index))
                {
                    return;
                }

                index.FieldDefinitionCollection.AddOrUpdate(
                    new FieldDefinition("searchableCategories", FieldDefinitionTypes.FullText));

                ((BaseIndexProvider)index).TransformingIndexValues += IndexerComponent_TransformingIndexvalues;
            }
Exemplo n.º 12
0
        public void Initialize()
        {
            if (!_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out IIndex index))
            {
                throw new InvalidOperationException($"No index found by name {Constants.UmbracoIndexes.ExternalIndexName}");
            }

            if (!(index is BaseIndexProvider indexProvider))
            {
                throw new InvalidOperationException("Could not cast");
            }

            indexProvider.TransformingIndexValues += IndexProviderTransformingIndexValues;
        }
        private IQuery InitialiseMemberQuery(BooleanOperation operation = BooleanOperation.And, string indexType = UmbracoIndexes.MembersIndexName)
        {
            if (examineManager.TryGetIndex(indexType, out var index))
            {
#if NET5_0_OR_GREATER
                var searcher = index.Searcher;
#else
                var searcher = index.GetSearcher();
#endif
                return(searcher.CreateQuery(IndexTypes.Member, defaultOperation: operation));
            }
            logger.LogWarning("Could not retrieve index {indexType}", indexType);
            return(null);
        }
Exemplo n.º 14
0
        public void Initialize()
        {
            IIndex externalIndex = null;

            if (_examineManager.TryGetIndex("ExternalIndex", out externalIndex))
            {
                // FieldDefinitionCollection contains all indexed fields
                externalIndex.FieldDefinitionCollection.AddOrUpdate(new FieldDefinition("contents", FieldDefinitionTypes.FullText));
                ((BaseIndexProvider)externalIndex).TransformingIndexValues += OnTransformingIndexValues;
            }
            else
            {
                throw new Exception("Index not found");
            }
        }
Exemplo n.º 15
0
        public void Initialize()
        {
            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                throw new InvalidOperationException("No index found by name ExternalIndex");
            }

            //we need to cast because BaseIndexProvider contains the TransformingIndexValues event
            if (!(index is BaseIndexProvider indexProvider))
            {
                throw new InvalidOperationException("Could not cast");
            }

            indexProvider.TransformingIndexValues += IndexProviderTransformingIndexValues;
        }
        public void Initialize()
        {
            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                _logger.Error <AddFullTextItemsToIndex>(new InvalidOperationException("No index found by name ExternalIndex"));
                return;
            }

            //we need to cast because BaseIndexProvider contains the TransformingIndexValues event
            if (!(index is BaseIndexProvider indexProvider))
            {
                _logger.Error <AddFullTextItemsToIndex>(new InvalidOperationException("Could not cast ExternalIndex to BaseIndexProvider"));
                return;
            }
            indexProvider.TransformingIndexValues += IndexProviderTransformingIndexValues;
        }
Exemplo n.º 17
0
        public override bool PerformRun()
        {
            if (!_fullTextConfig.IsFullTextIndexingEnabled())
            {
                return(false);
            }
            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                _logger.Error <PerformCacheTasks>(new InvalidOperationException("No index found by name ExternalIndex"));
                return(false);
            }

            try
            {
                using (_profilingLogger.DebugDuration <PerformCacheTasks>("PerformCacheTasks", "PerformCacheTasks done"))
                {
                    var tasks = _cacheService.GetCacheTasks();

                    foreach (var task in tasks)
                    {
                        _cacheService.SetTaskAsStarted(task);
                    }

                    foreach (var task in tasks)
                    {
                        var content = _contentService.GetById(task.NodeId);
                        if (content != null)
                        {
                            _cacheService.AddToCache(task.NodeId);
                            index.IndexItems(_valueSetBuilder.GetValueSets(content));
                        }
                        else
                        {
                            _cacheService.DeleteFromCache(task.NodeId);
                        }
                        _cacheService.DeleteCacheTask(task.Id);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Error <PerformCacheTasks>(e);
            }

            return(true);
        }
        public static IEnumerable <PublishedSearchResult> SearchChildren(this IPublishedContent content, IExamineManager examineManager, IUmbracoContextAccessor umbracoContextAccessor, string term, string indexName = null)
        {
            indexName = string.IsNullOrEmpty(indexName) ? Constants.UmbracoIndexes.ExternalIndexName : indexName;
            if (!examineManager.TryGetIndex(indexName, out var index))
            {
                throw new InvalidOperationException("No index found with name " + indexName);
            }

            //var t = term.Escape().Value;
            //var luceneQuery = "+parentID:" + content.Id + " +" + t;

            var query = index.Searcher.CreateQuery()
                        .Field("parentID", content.Id)
                        .And()
                        .ManagedQuery(term);
            var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();

            return(query.Execute().ToPublishedSearchResults(umbracoContext.Content));
        }
        public static IEnumerable <PublishedSearchResult> SearchDescendants(this IPublishedContent content, IExamineManager examineManager, IUmbracoContextAccessor umbracoContextAccessor, string term, string indexName = null)
        {
            indexName = string.IsNullOrEmpty(indexName) ? Constants.UmbracoIndexes.ExternalIndexName : indexName;
            if (!examineManager.TryGetIndex(indexName, out var index))
            {
                throw new InvalidOperationException("No index found with name " + indexName);
            }

            //var t = term.Escape().Value;
            //var luceneQuery = "+__Path:(" + content.Path.Replace("-", "\\-") + "*) +" + t;

            var query = index.Searcher.CreateQuery()
                        .Field(UmbracoExamineFieldNames.IndexPathFieldName, (content.Path + ",").MultipleCharacterWildcard())
                        .And()
                        .ManagedQuery(term);
            var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();

            return(query.Execute().ToPublishedSearchResults(umbracoContext.Content));
        }
Exemplo n.º 20
0
        protected virtual ISearcher GetSearcherByIndexName(IExamineManager examineManager, ISearchHelper searchHelper, string indexName)
        {
            // Get the index from the Examine manager
            if (!examineManager.TryGetIndex(indexName, out IIndex index))
            {
                throw new Exception($"Examine index {indexName} not found.");
            }

            // Get the searcher from the index
            ISearcher searcher = index.GetSearcher();

            if (searcher == null)
            {
                throw new Exception("Examine index {indexName} does not specify a searcher.");
            }

            // Return the searcher
            return(searcher);
        }
        /// <summary>Initializes the component.</summary>
        public void Initialize()
        {
            //get the index
            if (!_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out IIndex index))
            {
                return;
            }

            //we need to cast because BaseIndexProvider contains the TransformingIndexValues event
            if (!(index is BaseIndexProvider indexProvider))
            {
                throw new InvalidOperationException("Could not cast");
            }

            //handler
            indexProvider.TransformingIndexValues += IndexProviderTransformingIndexValues;

            //add a new field definition to the index
            index.FieldDefinitionCollection.TryAdd(new FieldDefinition("blogDateLong", FieldDefinitionTypes.Long));
        }
Exemplo n.º 22
0
        public ISearchResults Search(string searchQuery, int maxResults, float fuzzieness, string indexType, string[] nodeTypes, string[] properties)
        {
            if (!examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out var index))
            {
                throw new InvalidOperationException($"No index found by name {Constants.UmbracoIndexes.ExternalIndexName}");
            }

            var searcher          = index.GetSearcher();
            var query             = searcher.CreateQuery(indexType);
            var operation         = query.GroupedOr(new[] { SearchFields.NodeTypeAlias }, nodeTypes);
            var queryWords        = searchQuery.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
            var exactSearchPhrase = new ExactPhraseExamineValue(searchQuery);

            foreach (var word in queryWords)
            {
                operation.And().GroupedOr(properties, word.Fuzzy(fuzzieness), exactSearchPhrase);
            }

            return(operation.Execute(maxResults));
        }
Exemplo n.º 23
0
        public bool ReindexNode(string nodeIds)
        {
            if (!_fullTextConfig.IsFullTextIndexingEnabled())
            {
                _logger.Debug <IndexController>("FullTextIndexing is not enabled");
                return(false);
            }

            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                _logger.Error <IndexController>(new InvalidOperationException("No index found by name ExternalIndex"));
                return(false);
            }
            if (nodeIds == "*")
            {
                foreach (var content in Umbraco.ContentAtRoot())
                {
                    _cacheService.AddToCache(content.Id);
                    foreach (var descendant in content.Descendants())
                    {
                        _cacheService.AddToCache(descendant.Id);
                    }
                }
                index.CreateIndex();
                _indexRebuilder.RebuildIndex("ExternalIndex");
            }
            else
            {
                var ids = nodeIds.Split(',').Select(x => int.Parse(x));

                foreach (var id in ids)
                {
                    _cacheService.AddToCache(id);
                }
                index.IndexItems(_valueSetBuilder.GetValueSets(_contentService.GetByIds(ids).ToArray()));
            }

            return(true);
        }
Exemplo n.º 24
0
        public void Initialize()
        {
            // Get the member index
            if (!_examineManager.TryGetIndex(Constants.UmbracoIndexes.MembersIndexName, out IIndex index))
            {
                return;
            }

            // Add a custom fields
            var skills = new FieldDefinition("skills", FieldDefinitionTypes.FullText);

            index.FieldDefinitionCollection.AddOrUpdate(skills);

            var skillKeysValue = new FieldDefinition("skillKeys", FieldDefinitionTypes.InvariantCultureIgnoreCase);

            index.FieldDefinitionCollection.AddOrUpdate(skillKeysValue);

            var skillIdsValue = new FieldDefinition("skillIds", FieldDefinitionTypes.InvariantCultureIgnoreCase);

            index.FieldDefinitionCollection.AddOrUpdate(skillIdsValue);

            ((BaseIndexProvider)index).TransformingIndexValues += SGFMemberIndexComponent_TransformingIndexValues;
        }
        public IEnumerable <DataListItem> GetItems(Dictionary <string, object> config)
        {
            var examineIndex = config.GetValueAs("examineIndex", UmbConstants.UmbracoIndexes.ExternalIndexName);

            if (_examineManager.TryGetIndex(examineIndex, out var index) == true)
            {
                var luceneQuery = config.GetValueAs("luceneQuery", string.Empty);
                if (string.IsNullOrWhiteSpace(luceneQuery) == false)
                {
                    var nameField        = config.GetValueAs("nameField", _defaultNameField);
                    var valueField       = config.GetValueAs("valueField", _defaultValueField);
                    var iconField        = config.GetValueAs("iconField", _defaultIconField);
                    var descriptionField = config.GetValueAs("descriptionField", string.Empty);

                    var results = index
                                  .GetSearcher()
                                  .CreateQuery()
                                  .NativeQuery(luceneQuery)
                                  // NOTE: For any `OrderBy` complaints, refer to: https://github.com/Shazwazza/Examine/issues/126
                                  .OrderBy(new SortableField(nameField, SortType.String))
                                  .Execute();

                    if (results?.TotalItemCount > 0)
                    {
                        return(results.Select(x => new DataListItem
                        {
                            Name = x.Values.ContainsKey(nameField) == true ? x.Values[nameField] : x.Values[_defaultNameField],
                            Value = x.Values.ContainsKey(valueField) == true ? x.Values[valueField] : x.Values[_defaultValueField],
                            Icon = x.Values.ContainsKey(iconField) == true ? x.Values[iconField] : x.Values[_defaultIconField],
                            Description = x.Values.ContainsKey(descriptionField) == true ? x.Values[descriptionField] : null,
                        }));
                    }
                }
            }

            return(Enumerable.Empty <DataListItem>());
        }
Exemplo n.º 26
0
        /// <summary>
        /// Returns the <see cref="ISearcher"/> as specified by the specified <paramref name="options"/>.
        ///
        /// If <paramref name="options"/> doesn't specify a searcher, the searcher of <c>ExternalIndex</c> will be used as fallback.
        /// </summary>
        /// <param name="options">The search options.</param>
        /// <returns>The <see cref="ISearcher"/> to be used for the search.</returns>
        protected virtual ISearcher GetSearcher(ISearchOptions options)
        {
            ISearcher searcher;

            switch (options)
            {
            case ISearcherOptions searcherOptions:
                searcher = searcherOptions.Searcher;
                if (searcher != null)
                {
                    return(searcher);
                }
                break;

            case IGetSearcherOptions getSearcherOptions:
                searcher = getSearcherOptions.GetSearcher(_examine, this);
                if (searcher != null)
                {
                    return(searcher);
                }
                break;

            default:
                if (_examine.TryGetIndex(ExamineConstants.ExternalIndexName, out IIndex index))
                {
                    searcher = index.GetSearcher();
                    if (searcher != null)
                    {
                        return(searcher);
                    }
                }
                break;
            }

            throw new Exception($"Failed determining searcher from {options.GetType()}");
        }
Exemplo n.º 27
0
        private ISearchResults GetResults()
        {
            if (_examineManager.TryGetIndex("ExternalIndex", out var index))
            {
                var query = new StringBuilder();

                query.Append("(");

                switch (_search.SearchType)
                {
                case SearchType.MultiRelevance:

                    // We formulate the query differently depending on the input.
                    if (_search.SearchTerm.Contains('"'))
                    {
                        // If the user has enetered double quotes we don't bother
                        // searching for the full string
                        query.Append(QueryAllPropertiesOr(_search.SearchTermSplit, 1));
                    }
                    else if (!_search.SearchTerm.Contains('"') && !_search.SearchTerm.Contains(' '))
                    {
                        // if there's no spaces or quotes we don't need to get the quoted term and boost it
                        query.Append(QueryAllPropertiesOr(_search.SearchTermSplit, 1));
                    }
                    else
                    {
                        // otherwise we search first for the entire query in quotes,
                        // then for each term in the query OR'd together.
                        query.AppendFormat("({0} OR {1})",
                                           QueryAllPropertiesOr(_search.SearchTermQuoted, 2)
                                           , QueryAllPropertiesOr(_search.SearchTermSplit, 1)
                                           );
                    }

                    break;

                case SearchType.MultiAnd:

                    if (_search.SearchTerm.Contains('"'))
                    {
                        // If the user has enetered double quotes we don't bother
                        // searching for the full string
                        query.Append(QueryAllPropertiesAnd(_search.SearchTermSplit, 1.0));
                    }
                    else if (!_search.SearchTerm.Contains('"') && !_search.SearchTerm.Contains(' '))
                    {
                        // if there's no spaces or quotes we don't need to get the quoted term and boost it
                        query.Append(QueryAllPropertiesAnd(_search.SearchTermSplit, 1));
                    }
                    else
                    {
                        // otherwise we search first for the entire query in quotes,
                        // then for each term in the query OR'd together.
                        query.AppendFormat("{0} OR {1}",
                                           QueryAllPropertiesAnd(_search.SearchTermQuoted, 2)
                                           , QueryAllPropertiesAnd(_search.SearchTermSplit, 1)
                                           );
                    }
                    break;

                case SearchType.SimpleOr:

                    query.Append(QueryAllProperties(_search.SearchTermSplit, 1.0, "OR", true));
                    break;

                case SearchType.AsEntered:

                    query.Append(QueryAllPropertiesAnd(_search.SearchTermSplit, 1.0));
                    break;
                }
                query.Append(")");

                if (_search.RootNodeIds.Any())
                {
                    var pathName      = _fullTextConfig.GetPathFieldName();
                    var rootNodeGroup = string.Join(" OR ", _search.RootNodeIds.Select(x => string.Format("{0}:{1}", pathName, x.ToString())));
                    query.AppendFormat(" AND ({0})", rootNodeGroup);
                }

                query.Append($" AND (__IndexType:content AND __Published_{_search.Culture}:y)");

                var searcher = index.GetSearcher();
                _logger.Info <SearchService>("Trying to search for {query}", query.ToString());
                return(searcher.CreateQuery().NativeQuery(query.ToString()).Execute(_search.PageLength * _currentPage));
            }

            return(null);
        }
Exemplo n.º 28
0
        /// <summary>
        /// Searches Examine for results based on the entity type
        /// </summary>
        /// <param name="query"></param>
        /// <param name="entityType"></param>
        /// <param name="totalFound"></param>
        /// <param name="searchFrom">
        /// A starting point for the search, generally a node id, but for members this is a member type alias
        /// </param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="ignoreUserStartNodes">If set to true, user and group start node permissions will be ignored.</param>
        /// <returns></returns>
        public IEnumerable <SearchResultEntity> ExamineSearch(
            string query,
            UmbracoEntityTypes entityType,
            int pageSize,
            long pageIndex, out long totalFound, string searchFrom = null, bool ignoreUserStartNodes = false)
        {
            var sb = new StringBuilder();

            string type;
            var    indexName = Constants.UmbracoIndexes.InternalIndexName;
            var    fields    = new List <string> {
                "id", "__NodeId", "__Key"
            };

            // TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string
            // manipulation for things like start paths, member types, etc...
            //if (Examine.ExamineExtensions.TryParseLuceneQuery(query))
            //{

            //}

            //special GUID check since if a user searches on one specifically we need to escape it
            if (Guid.TryParse(query, out var g))
            {
                query = "\"" + g.ToString() + "\"";
            }

            switch (entityType)
            {
            case UmbracoEntityTypes.Member:
                indexName = Constants.UmbracoIndexes.MembersIndexName;
                type      = "member";
                fields.AddRange(new[] { "email", "loginName" });
                if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
                {
                    sb.Append("+__NodeTypeAlias:");
                    sb.Append(searchFrom);
                    sb.Append(" ");
                }
                break;

            case UmbracoEntityTypes.Media:
                type = "media";
                fields.AddRange(new[] { UmbracoExamineIndex.UmbracoFileFieldName });
                var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService);
                AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
                break;

            case UmbracoEntityTypes.Document:
                type = "content";
                var allContentStartNodes = _umbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(_entityService);
                AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
                break;

            default:
                throw new NotSupportedException("The " + typeof(UmbracoTreeSearcher) + " currently does not support searching against object type " + entityType);
            }

            if (!_examineManager.TryGetIndex(indexName, out var index))
            {
                throw new InvalidOperationException("No index found by name " + indexName);
            }

            var internalSearcher = index.GetSearcher();

            if (!BuildQuery(sb, query, searchFrom, fields, type))
            {
                totalFound = 0;
                return(Enumerable.Empty <SearchResultEntity>());
            }

            var result = internalSearcher.CreateQuery().NativeQuery(sb.ToString())
                         //only return the number of items specified to read up to the amount of records to fill from 0 -> the number of items on the page requested
                         .Execute(Convert.ToInt32(pageSize * (pageIndex + 1)));

            totalFound = result.TotalItemCount;

            var pagedResult = result.Skip(Convert.ToInt32(pageIndex));

            switch (entityType)
            {
            case UmbracoEntityTypes.Member:
                return(MemberFromSearchResults(pagedResult.ToArray()));

            case UmbracoEntityTypes.Media:
                return(MediaFromSearchResults(pagedResult));

            case UmbracoEntityTypes.Document:
                return(ContentFromSearchResults(pagedResult));

            default:
                throw new NotSupportedException("The " + typeof(UmbracoTreeSearcher) + " currently does not support searching against object type " + entityType);
            }
        }
        public IEnumerable <ISearchResult> Search(string query, UmbracoEntityTypes entityType, int pageSize, long pageIndex, out long totalFound, string searchFrom = null, bool ignoreUserStartNodes = false)
        {
            var sb = new StringBuilder();

            string type;
            var    indexName = Constants.UmbracoIndexes.InternalIndexName;
            var    fields    = _treeSearcherFields.GetBackOfficeFields().ToList();

            ISet <string> fieldsToLoad = new HashSet <string>(_treeSearcherFields.GetBackOfficeFieldsToLoad());

            // TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string
            // manipulation for things like start paths, member types, etc...
            //if (Examine.ExamineExtensions.TryParseLuceneQuery(query))
            //{

            //}

            //special GUID check since if a user searches on one specifically we need to escape it
            if (Guid.TryParse(query, out var g))
            {
                query = "\"" + g.ToString() + "\"";
            }

            var currentUser = _backOfficeSecurityAccessor?.BackOfficeSecurity?.CurrentUser;

            switch (entityType)
            {
            case UmbracoEntityTypes.Member:
                indexName = Constants.UmbracoIndexes.MembersIndexName;
                type      = "member";
                fields.AddRange(_treeSearcherFields.GetBackOfficeMembersFields());
                foreach (var field in _treeSearcherFields.GetBackOfficeMembersFieldsToLoad())
                {
                    fieldsToLoad.Add(field);
                }

                if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
                {
                    sb.Append("+__NodeTypeAlias:");
                    sb.Append(searchFrom);
                    sb.Append(" ");
                }
                break;

            case UmbracoEntityTypes.Media:
                type = "media";
                fields.AddRange(_treeSearcherFields.GetBackOfficeMediaFields());
                foreach (var field in _treeSearcherFields.GetBackOfficeMediaFieldsToLoad())
                {
                    fieldsToLoad.Add(field);
                }

                var allMediaStartNodes = currentUser != null
                        ? currentUser.CalculateMediaStartNodeIds(_entityService, _appCaches)
                        : Array.Empty <int>();

                AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
                break;

            case UmbracoEntityTypes.Document:
                type = "content";
                fields.AddRange(_treeSearcherFields.GetBackOfficeDocumentFields());
                foreach (var field in _treeSearcherFields.GetBackOfficeDocumentFieldsToLoad())
                {
                    fieldsToLoad.Add(field);
                }
                var allContentStartNodes = currentUser != null
                        ? currentUser.CalculateContentStartNodeIds(_entityService, _appCaches)
                        : Array.Empty <int>();

                AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
                break;

            default:
                throw new NotSupportedException("The " + typeof(BackOfficeExamineSearcher) + " currently does not support searching against object type " + entityType);
            }

            if (!_examineManager.TryGetIndex(indexName, out var index))
            {
                throw new InvalidOperationException("No index found by name " + indexName);
            }

            if (!BuildQuery(sb, query, searchFrom, fields, type))
            {
                totalFound = 0;
                return(Enumerable.Empty <ISearchResult>());
            }

            var result = index.Searcher
                         .CreateQuery()
                         .NativeQuery(sb.ToString())
                         .SelectFields(fieldsToLoad)
                         //only return the number of items specified to read up to the amount of records to fill from 0 -> the number of items on the page requested
                         .Execute(QueryOptions.SkipTake(Convert.ToInt32(pageSize * pageIndex), pageSize));

            totalFound = result.TotalItemCount;

            var pagedResult = result.Skip(Convert.ToInt32(pageIndex));

            return(pagedResult);
        }
Exemplo n.º 30
0
        public IEnumerable <IPublishedContent> Search(string term, string indexName, int blogArchiveNodeId, int pageSize, int pageIndex, out long totalResults)
        {
            var splitSearch = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            //The fields to search on and their 'weight' (importance)
            var fields = new Dictionary <string, int>
            {
                { "markdown", 2 },
                { "richText", 2 },
                { "nodeName", 3 },
                { "tags", 1 },
                { "categories", 1 },
                { "umbracoUrlName", 3 }
            };

            //The multipliers for match types
            const int exactMatch = 5;
            const int termMatch  = 2;

            var fieldQuery = new StringBuilder();

            //build field query
            foreach (var field in fields)
            {
                //full exact match (which has a higher boost)
                fieldQuery.Append($"{field.Key}:{"\"" + term + "\""}^{field.Value*exactMatch}");
                fieldQuery.Append(" ");
                //NOTE: Phrase match wildcard isn't really supported unless you use the Lucene
                // API like ComplexPhraseWildcardSomethingOrOther...
                //split match
                foreach (var s in splitSearch)
                {
                    //match on each term, no wildcard, higher boost
                    fieldQuery.Append($"{field.Key}:{s}^{field.Value*termMatch}");
                    fieldQuery.Append(" ");

                    //match on each term, with wildcard
                    fieldQuery.Append($"{field.Key}:{s}*");
                    fieldQuery.Append(" ");
                }
            }

            indexName = indexName.IsNullOrWhiteSpace() ? Constants.UmbracoIndexes.ExternalIndexName : indexName;

            if (!_examineManager.TryGetIndex(indexName, out var index))
            {
                throw new InvalidOperationException("No index found by name " + indexName);
            }

            var searcher = index.GetSearcher();

            var criteria = searcher.CreateQuery()
                           .Field("parentID", blogArchiveNodeId)
                           .And()
                           .NativeQuery($" +({fieldQuery})");

            var searchResult = criteria.Execute(
                //don't return more results than we need for the paging
                pageSize * (pageIndex + 1));

            var result = searchResult.ToPublishedSearchResults(_umbracoContext.PublishedSnapshot.Content);

            totalResults = searchResult.TotalItemCount;

            return(result.Select(x => x.Content));
        }