public async Task <IEnumerable <ContentPickerResult> > Search(ContentPickerSearchContext searchContext)
        {
            var indexName = "Search";

            var fieldSettings = searchContext.PartFieldDefinition?.GetSettings <ContentPickerFieldLuceneEditorSettings>();

            if (!string.IsNullOrWhiteSpace(fieldSettings?.Index))
            {
                indexName = fieldSettings.Index;
            }

            if (!_luceneIndexProvider.Exists(indexName))
            {
                return(new List <ContentPickerResult>());
            }

            var results = new List <ContentPickerResult>();

            await _luceneIndexProvider.SearchAsync(indexName, searcher =>
            {
                Query query = null;

                if (string.IsNullOrWhiteSpace(searchContext.Query))
                {
                    query = new MatchAllDocsQuery();
                }
                else
                {
                    query = new WildcardQuery(new Term("Content.ContentItem.DisplayText.Analyzed", searchContext.Query.ToLowerInvariant() + "*"));
                }

                var filter = new FieldCacheTermsFilter("Content.ContentItem.ContentType", searchContext.ContentTypes.ToArray());

                var docs = searcher.Search(query, filter, 50, Sort.RELEVANCE);

                foreach (var hit in docs.ScoreDocs)
                {
                    var doc = searcher.Doc(hit.Doc);

                    results.Add(new ContentPickerResult
                    {
                        ContentItemId = doc.GetField("ContentItemId").GetStringValue(),
                        DisplayText   = doc.GetField("Content.ContentItem.DisplayText").GetStringValue(),
                        HasPublished  = doc.GetField("Content.ContentItem.Published").GetStringValue() == "true" ? true : false
                    });
                }

                return(Task.CompletedTask);
            });

            return(results.OrderBy(x => x.DisplayText));
        }
        public async Task <ActionResult> CreatePOST(AdminEditViewModel model)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Unauthorized());
            }

            ValidateModel(model);

            if (_luceneIndexManager.Exists(model.IndexName))
            {
                ModelState.AddModelError(nameof(AdminEditViewModel.IndexName), S["An index named {0} already exists."]);
            }

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            try
            {
                // We call Rebuild in order to reset the index state cursor too in case the same index
                // name was also used previously.
                _luceneIndexingService.RebuildIndex(model.IndexName);
                await _luceneIndexingService.ProcessContentItemsAsync();
            }
            catch (Exception e)
            {
                _notifier.Error(H["An error occurred while creating the index"]);
                Logger.LogError("An error occurred while creating an index", e);
                return(View(model));
            }

            _notifier.Success(H["Index <em>{0}</em> created successfully", model.IndexName]);

            return(RedirectToAction("Index"));
        }
        public Task ExecuteAsync(RecipeExecutionContext context)
        {
            if (!String.Equals(context.Name, "lucene-index", StringComparison.OrdinalIgnoreCase))
            {
                return(Task.CompletedTask);
            }

            var model = context.Step.ToObject <LuceneIndexModel>();

            foreach (var index in model.Indices)
            {
                if (!_luceneIndexManager.Exists(index))
                {
                    _luceneIndexManager.CreateIndex(index);
                }
            }

            return(Task.CompletedTask);
        }
        public async Task ExecuteAsync(RecipeExecutionContext context)
        {
            if (!String.Equals(context.Name, "lucene-index", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            var indices = context.Step["Indices"];

            if (indices != null)
            {
                foreach (var index in indices)
                {
                    var luceneIndexSettings = index.ToObject <Dictionary <string, LuceneIndexSettings> >().FirstOrDefault();

                    if (!_luceneIndexManager.Exists(luceneIndexSettings.Key))
                    {
                        luceneIndexSettings.Value.IndexName = luceneIndexSettings.Key;
                        await _luceneIndexingService.CreateIndexAsync(luceneIndexSettings.Value);
                    }
                }
            }
        }
Exemple #5
0
        public async Task <ActionResult> EditPost(LuceneIndexSettingsViewModel model, string[] indexedContentTypes)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Forbid());
            }

            ValidateModel(model);

            if (model.IsCreate)
            {
                if (_luceneIndexManager.Exists(model.IndexName))
                {
                    ModelState.AddModelError(nameof(LuceneIndexSettingsViewModel.IndexName), S["An index named {0} already exists.", model.IndexName]);
                }
            }
            else
            {
                if (!_luceneIndexManager.Exists(model.IndexName))
                {
                    ModelState.AddModelError(nameof(LuceneIndexSettingsViewModel.IndexName), S["An index named {0} doesn't exist.", model.IndexName]);
                }
            }

            if (!ModelState.IsValid)
            {
                model.Cultures = CultureInfo.GetCultures(CultureTypes.AllCultures)
                                 .Select(x => new SelectListItem {
                    Text = x.Name + " (" + x.DisplayName + ")", Value = x.Name
                }).Prepend(new SelectListItem {
                    Text = S["Any culture"], Value = "any"
                });
                model.Analyzers = _luceneAnalyzerManager.GetAnalyzers()
                                  .Select(x => new SelectListItem {
                    Text = x.Name, Value = x.Name
                });
                return(View(model));
            }

            if (model.IsCreate)
            {
                try
                {
                    var settings = new LuceneIndexSettings {
                        IndexName = model.IndexName, AnalyzerName = model.AnalyzerName, IndexLatest = model.IndexLatest, IndexedContentTypes = indexedContentTypes, Culture = model.Culture ?? ""
                    };

                    // We call Rebuild in order to reset the index state cursor too in case the same index
                    // name was also used previously.
                    await _luceneIndexingService.CreateIndexAsync(settings);
                }
                catch (Exception e)
                {
                    _notifier.Error(H["An error occurred while creating the index."]);
                    _logger.LogError(e, "An error occurred while creating an index.");
                    return(View(model));
                }

                _notifier.Success(H["Index <em>{0}</em> created successfully.", model.IndexName]);
            }
            else
            {
                try
                {
                    var settings = new LuceneIndexSettings {
                        IndexName = model.IndexName, AnalyzerName = model.AnalyzerName, IndexLatest = model.IndexLatest, IndexedContentTypes = indexedContentTypes, Culture = model.Culture ?? ""
                    };

                    await _luceneIndexingService.UpdateIndexAsync(settings);
                }
                catch (Exception e)
                {
                    _notifier.Error(H["An error occurred while editing the index."]);
                    _logger.LogError(e, "An error occurred while editing an index.");
                    return(View(model));
                }

                _notifier.Success(H["Index <em>{0}</em> modified successfully, <strong>please consider doing a rebuild on the index.</strong>", model.IndexName]);
            }

            return(RedirectToAction("Index"));
        }
Exemple #6
0
        public async Task <IActionResult> Search(SearchIndexViewModel viewModel, PagerSlimParameters pagerParameters)
        {
            var permissionsProvider = _permissionProviders.FirstOrDefault(x => x.GetType().FullName == "OrchardCore.Lucene.Permissions");
            var permissions         = await permissionsProvider.GetPermissionsAsync();

            var siteSettings = await _siteService.GetSiteSettingsAsync();

            var searchSettings = siteSettings.As <LuceneSettings>();

            if (permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index") != null)
            {
                if (!await _authorizationService.AuthorizeAsync(User, permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index")))
                {
                    return(this.ChallengeOrForbid());
                }
            }
            else
            {
                _logger.LogInformation("Couldn't execute search. The search index doesn't exist.");
                return(BadRequest("Search is not configured."));
            }

            if (searchSettings.SearchIndex != null && !_luceneIndexProvider.Exists(searchSettings.SearchIndex))
            {
                _logger.LogInformation("Couldn't execute search. The search index doesn't exist.");
                return(BadRequest("Search is not configured."));
            }

            var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null)
            {
                _logger.LogInformation("Couldn't execute search. No Lucene settings was defined.");
                return(BadRequest("Search is not configured."));
            }

            var luceneIndexSettings = await _luceneIndexSettingsService.GetSettingsAsync(searchSettings.SearchIndex);

            if (luceneIndexSettings == null)
            {
                _logger.LogInformation($"Couldn't execute search. No Lucene index settings was defined for ({searchSettings.SearchIndex}) index.");
                return(BadRequest($"Search index ({searchSettings.SearchIndex}) is not configured."));
            }

            if (string.IsNullOrWhiteSpace(viewModel.Terms))
            {
                return(View(new SearchIndexViewModel
                {
                    SearchForm = new SearchFormViewModel("Search__Form")
                    {
                    },
                }));
            }

            var pager = new PagerSlim(pagerParameters, siteSettings.PageSize);

            // We Query Lucene index
            var analyzer    = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneIndexSettings.IndexName));
            var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, analyzer);
            var query       = queryParser.Parse(QueryParser.Escape(viewModel.Terms));

            // Fetch one more result than PageSize to generate "More" links
            var start = 0;
            var end   = pager.PageSize + 1;

            if (pagerParameters.Before != null)
            {
                start = Convert.ToInt32(pagerParameters.Before) - pager.PageSize - 1;
                end   = Convert.ToInt32(pagerParameters.Before);
            }
            else if (pagerParameters.After != null)
            {
                start = Convert.ToInt32(pagerParameters.After);
                end   = Convert.ToInt32(pagerParameters.After) + pager.PageSize + 1;
            }

            var contentItemIds = await _searchQueryService.ExecuteQueryAsync(query, searchSettings.SearchIndex, start, end);

            // We Query database to retrieve content items.
            IQuery <ContentItem> queryDb;

            if (luceneIndexSettings.IndexLatest)
            {
                queryDb = _session.Query <ContentItem, ContentItemIndex>()
                          .Where(x => x.ContentItemId.IsIn(contentItemIds) && x.Latest == true)
                          .Take(pager.PageSize + 1);
            }
            else
            {
                queryDb = _session.Query <ContentItem, ContentItemIndex>()
                          .Where(x => x.ContentItemId.IsIn(contentItemIds) && x.Published == true)
                          .Take(pager.PageSize + 1);
            }

            var containedItems = await queryDb.ListAsync();

            // We set the PagerSlim before and after links
            if (pagerParameters.After != null || pagerParameters.Before != null)
            {
                if (start + 1 > 1)
                {
                    pager.Before = (start + 1).ToString();
                }
                else
                {
                    pager.Before = null;
                }
            }

            if (containedItems.Count() == pager.PageSize + 1)
            {
                pager.After = (end - 1).ToString();
            }
            else
            {
                pager.After = null;
            }

            var model = new SearchIndexViewModel
            {
                Terms      = viewModel.Terms,
                SearchForm = new SearchFormViewModel("Search__Form")
                {
                    Terms = viewModel.Terms
                },
                SearchResults = new SearchResultsViewModel("Search__Results")
                {
                    ContentItems = containedItems.Take(pager.PageSize)
                },
                Pager = (await New.PagerSlim(pager)).UrlParams(new Dictionary <string, string>()
                {
                    { "Terms", viewModel.Terms }
                })
            };

            return(View(model));
        }
        public async Task <IActionResult> Search(SearchIndexViewModel viewModel, PagerParameters pagerParameters)
        {
            var permissionsProvider = _permissionProviders.FirstOrDefault(x => x.GetType().FullName == "OrchardCore.Lucene.Permissions");
            var permissions         = await permissionsProvider.GetPermissionsAsync();

            var siteSettings = await _siteService.GetSiteSettingsAsync();

            var searchSettings = siteSettings.As <LuceneSettings>();

            if (permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index") != null)
            {
                if (!await _authorizationService.AuthorizeAsync(User, permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index")))
                {
                    return(this.ChallengeOrForbid());
                }
            }
            else
            {
                _logger.LogInformation("Couldn't execute search. The search index doesn't exist.");
                return(BadRequest("Search is not configured."));
            }

            if (searchSettings.SearchIndex != null && !_luceneIndexProvider.Exists(searchSettings.SearchIndex))
            {
                _logger.LogInformation("Couldn't execute search. The search index doesn't exist.");
                return(BadRequest("Search is not configured."));
            }

            var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null)
            {
                _logger.LogInformation("Couldn't execute search. No Lucene settings was defined.");
                return(BadRequest("Search is not configured."));
            }

            var luceneIndexSettings = await _luceneIndexSettingsService.GetSettingsAsync(searchSettings.SearchIndex);

            if (luceneIndexSettings == null)
            {
                _logger.LogInformation($"Couldn't execute search. No Lucene index settings was defined for ({searchSettings.SearchIndex}) index.");
                return(BadRequest($"Search index ({searchSettings.SearchIndex}) is not configured."));
            }

            //if (string.IsNullOrWhiteSpace(viewModel.Terms))
            //{
            //    return View(new SearchIndexViewModel
            //    {
            //        SearchForm = new SearchFormViewModel("Search__Form") { },
            //    });
            //}

            var pager = new Pager(pagerParameters, siteSettings.PageSize);

            // We Query Lucene index
            var analyzer    = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneIndexSettings.IndexName));
            var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, analyzer);
            var query       = string.IsNullOrWhiteSpace(viewModel.Terms)
                ? new MatchAllDocsQuery()
                : queryParser.Parse(QueryParser.Escape(viewModel.Terms));

            // Fetch one more result than PageSize to generate "More" links
            var start = Math.Max(0, (pager.Page - 1) * pager.PageSize);
            var end   = Math.Max(start, start + pager.PageSize);

            var queryContentItems = (await _searchQueryService.ExecuteQueryAsync(query, searchSettings.SearchIndex, start, end));

            // We Query database to retrieve content items.
            IQuery <ContentItem> queryDb;

            if (luceneIndexSettings.IndexLatest)
            {
                queryDb = _session.Query <ContentItem, ContentItemIndex>()
                          .Where(x => x.ContentItemId.IsIn(queryContentItems.Item1) && x.Latest == true)
                          .Take(pager.PageSize);
            }
            else
            {
                queryDb = _session.Query <ContentItem, ContentItemIndex>()
                          .Where(x => x.ContentItemId.IsIn(queryContentItems.Item1) && x.Published == true)
                          .Take(pager.PageSize);
            }

            // Sort the content items by their rank in the search results returned by Lucene.
            var containedItems = (await queryDb.ListAsync()).OrderBy(x => queryContentItems.Item1.IndexOf(x.ContentItemId));

            var model = new SearchIndexViewModel
            {
                Terms      = viewModel.Terms,
                SearchForm = new SearchFormViewModel("Search__Form")
                {
                    Terms = viewModel.Terms
                },
                SearchResults = new SearchResultsViewModel("Search__Results")
                {
                    ContentItems = containedItems.Take(pager.PageSize)
                },
                Pager = (await New.Pager(pager)).TotalItemCount(queryContentItems.Item2).UrlParams(new Dictionary <string, string>()
                {
                    { "Terms", viewModel.Terms }
                })
            };

            return(View(model));
        }
Exemple #8
0
        public async Task <IActionResult> Index(string id, string q, PagerParameters pagerParameters)
        {
            var siteSettings = await _siteService.GetSiteSettingsAsync();

            var pager = new Pager(pagerParameters, siteSettings.PageSize);

            var indexName = "Search";

            if (!string.IsNullOrWhiteSpace(id))
            {
                indexName = id;
            }

            if (!_luceneIndexProvider.Exists(indexName))
            {
                return(NotFound());
            }

            if (string.IsNullOrWhiteSpace(q))
            {
                return(View(new SearchIndexViewModel
                {
                    Pager = pager,
                    IndexName = id,
                    ContentItems = Enumerable.Empty <ContentItem>()
                }));
            }

            var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            if (luceneSettings == null)
            {
                Logger.LogInformation("Couldn't execute search. No Lucene settings was defined.");

                return(View(new SearchIndexViewModel
                {
                    HasMoreResults = false,
                    Query = q,
                    Pager = pager,
                    IndexName = id,
                    ContentItems = Enumerable.Empty <ContentItem>()
                }));
            }

            var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, new StandardAnalyzer(LuceneSettings.DefaultVersion));
            var query       = queryParser.Parse(QueryParser.Escape(q));

            var contentItemIds = new List <string>();

            await _luceneIndexProvider.SearchAsync(indexName, searcher =>
            {
                // Fetch one more result than PageSize to generate "More" links
                var collector = TopScoreDocCollector.Create(pager.PageSize + 1, true);

                searcher.Search(query, collector);
                var hits = collector.GetTopDocs(pager.GetStartIndex(), pager.PageSize + 1);

                foreach (var hit in hits.ScoreDocs)
                {
                    var d = searcher.Doc(hit.Doc, IdSet);
                    contentItemIds.Add(d.GetField("ContentItemId").GetStringValue());
                }

                return(Task.CompletedTask);
            });

            var contentItems = new List <ContentItem>();

            foreach (var contentItemId in contentItemIds.Take(pager.PageSize))
            {
                var contentItem = await _contentManager.GetAsync(contentItemId);

                if (contentItem != null)
                {
                    contentItems.Add(contentItem);
                }
            }

            var model = new SearchIndexViewModel
            {
                HasMoreResults = contentItemIds.Count > pager.PageSize,
                Query          = q,
                Pager          = pager,
                IndexName      = id,
                ContentItems   = contentItems
            };

            return(View(model));
        }
        public async Task <IActionResult> Index(string id, string q, PagerParameters pagerParameters)
        {
            var siteSettings = await _siteService.GetSiteSettingsAsync();

            var pager = new Pager(pagerParameters, siteSettings.PageSize);

            var indexName = "Search";

            if (!string.IsNullOrWhiteSpace(id))
            {
                indexName = id;
            }

            if (!_luceneIndexProvider.Exists(indexName))
            {
                return(NotFound());
            }

            if (string.IsNullOrWhiteSpace(q))
            {
                return(View(new SearchIndexViewModel
                {
                    Pager = pager,
                    IndexName = id,
                    ContentItems = Enumerable.Empty <ContentItem>()
                }));
            }

            var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null)
            {
                Logger.LogInformation("Couldn't execute search. No Lucene settings was defined.");

                return(View(new SearchIndexViewModel
                {
                    HasMoreResults = false,
                    Query = q,
                    Pager = pager,
                    IndexName = id,
                    ContentItems = Enumerable.Empty <ContentItem>()
                }));
            }

            var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, new StandardAnalyzer(LuceneSettings.DefaultVersion));
            var query       = queryParser.Parse(QueryParser.Escape(q));

            int start = pager.GetStartIndex(), size = pager.PageSize, end = size + 1;// Fetch one more result than PageSize to generate "More" links
            var contentItemIds = await _searchQueryService.ExecuteQueryAsync(query, indexName, start, end);

            var contentItems = new List <ContentItem>();

            foreach (var contentItemId in contentItemIds.Take(size))
            {
                var contentItem = await _contentManager.GetAsync(contentItemId);

                if (contentItem != null)
                {
                    contentItems.Add(contentItem);
                }
            }

            var model = new SearchIndexViewModel
            {
                HasMoreResults = contentItemIds.Count > size,
                Query          = q,
                Pager          = pager,
                IndexName      = id,
                ContentItems   = contentItems
            };

            return(View(model));
        }