public override IDisplayResult Edit(LuceneQuery query, IUpdateModel updater)
        {
            return(Initialize <LuceneQueryViewModel>("LuceneQuery_Edit", async model =>
            {
                model.Query = query.Template;
                model.Index = query.Index;
                model.ReturnContentItems = query.ReturnContentItems;
                model.Indices = (await _luceneIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();

                // Extract query from the query string if we come from the main query editor
                if (String.IsNullOrEmpty(query.Template))
                {
                    await updater.TryUpdateModelAsync(model, "", m => m.Query);
                }
            }).Location("Content:5"));
        }
        public override async Task <IDisplayResult> EditAsync(LuceneSettings section, BuildEditorContext context)
        {
            var user = _httpContextAccessor.HttpContext?.User;

            if (!await _authorizationService.AuthorizeAsync(user, Permissions.ManageIndexes))
            {
                return(null);
            }

            return(Initialize <LuceneSettingsViewModel>("LuceneSettings_Edit", async model =>
            {
                model.SearchIndex = section.SearchIndex;
                model.SearchFields = String.Join(", ", section.DefaultSearchFields ?? new string[0]);
                model.SearchIndexes = (await _luceneIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName);
            }).Location("Content:2").OnGroup(GroupId));
        }
Ejemplo n.º 3
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));
        }
Ejemplo n.º 4
0
        public async Task <LuceneQueryResults> Query(AdminQueryViewModel model, Boolean returnContentItems)
        {
            //if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            //{
            //    return Unauthorized();
            //}

            // model.Indices = _luceneIndexManager.List().ToArray();
            model.Indices = (await _luceneIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();

            // Can't query if there are no indices
            //if (model.Indices.Length == 0)
            //{
            //    return RedirectToAction("Index");
            //}

            if (String.IsNullOrEmpty(model.IndexName))
            {
                model.IndexName = model.Indices[0];
            }

            //if (!_luceneIndexManager.Exists(model.IndexName))
            //{
            //    return NotFound();
            //}

            //if (String.IsNullOrWhiteSpace(model.DecodedQuery))
            //{
            //    return View(model);
            //}

            if (String.IsNullOrEmpty(model.Parameters))
            {
                model.Parameters = "{ }";
            }

            //  var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            //  var stopwatch = new Stopwatch();
            //stopwatch.Start();

            var luceneQueryResults = new LuceneQueryResults();

            await _luceneIndexManager.SearchAsync(model.IndexName, async searcher =>
            {
                var analyzer = _luceneAnalyzerManager.CreateAnalyzer("standardanalyzer");
                var context  = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);

                var templateContext = _liquidTemplateManager.Context;// new TemplateContext();
                var parameters      = JsonConvert.DeserializeObject <Dictionary <string, object> >(model.Parameters);

                foreach (var parameter in parameters)
                {
                    templateContext.SetValue(parameter.Key, parameter.Value);
                }

                var tokenizedContent = await _liquidTemplateManager.RenderAsync(model.DecodedQuery, NullEncoder.Default, templateContext);

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var docs = await _queryService.SearchAsync(context, parameterizedQuery);
                    //  model.Documents = docs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();

                    if (returnContentItems)
                    {
                        // Load corresponding content item versions
                        var contentItemVersionIds = docs.TopDocs.ScoreDocs.Select(x => searcher.Doc(x.Doc).Get("Content.ContentItem.ContentItemVersionId")).ToArray();
                        var contentItems          = await _session.Query <ContentItem, ContentItemIndex>(x => x.ContentItemVersionId.IsIn(contentItemVersionIds)).ListAsync();

                        // Reorder the result to preserve the one from the lucene query
                        var indexed = contentItems.ToDictionary(x => x.ContentItemVersionId, x => x);
                        luceneQueryResults.Items = contentItemVersionIds.Select(x => indexed[x]).ToArray();
                    }
                    else
                    {
                        var results = new List <JObject>();
                        foreach (var document in docs.TopDocs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)))
                        {
                            results.Add(new JObject(document.Select(x => new JProperty(x.Name, x.GetStringValue()))));
                        }

                        luceneQueryResults.Items = results;
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "Error while executing query");
                    //  ModelState.AddModelError(nameof(model.DecodedQuery), "Invalid query");
                }

                // stopwatch.Stop();
                // model.Elapsed = stopwatch.Elapsed;
            });

            return(luceneQueryResults);
        }
        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));
        }