public async Task <IList <string> > ExecuteQueryAsync(Query query, string indexName, int start, int end)
        {
            var contentItemIds = new List <string>();

            await _luceneIndexManager.SearchAsync(indexName, searcher =>
            {
                if (end > 0)
                {
                    var collector = TopScoreDocCollector.Create(end, true);

                    searcher.Search(query, collector);
                    var hits = collector.GetTopDocs(start, end);

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

                return(Task.CompletedTask);
            });

            return(contentItemIds);
        }
        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));
        }
Beispiel #3
0
        public async Task <Tuple <List <string>, int> > ExecuteQueryAsync(Query query, string indexName, int start = 0, int end = 20)
        {
            var contentItemIds = new List <string>();
            var totalCount     = 0;
            await _luceneIndexManager.SearchAsync(indexName, searcher =>
            {
                TopDocs hits;
                if (query is MatchAllDocsQuery)
                {
                    hits = searcher.Search(query, end, new Sort(new SortField("Content.ContentItem.CreatedUtc", SortFieldType.DOUBLE, true)));
                }
                else
                {
                    var collector = TopScoreDocCollector.Create(end, true);
                    searcher.Search(query, collector);
                    hits = collector.GetTopDocs(start, end);
                }

                totalCount = hits.TotalHits;
                if (start >= totalCount)
                {
                    return(Task.CompletedTask);
                }
                var size = end - start;
                if (start + size > totalCount)
                {
                    size = totalCount - start;
                }
                foreach (var hit in hits.ScoreDocs.AsSpan().Slice(start, size))
                {
                    var d = searcher.Doc(hit.Doc, IdSet);
                    contentItemIds.Add(d.GetField("ContentItemId").GetStringValue());
                }

                return(Task.CompletedTask);
            });

            return(Tuple.Create(contentItemIds, totalCount));
        }
Beispiel #4
0
        public async Task <IActionResult> Query(AdminQueryViewModel model, [FromServices] ITokenizer tokenizer)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Unauthorized());
            }

            model.Indices = _luceneIndexManager.List().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();

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

                var tokenizedContent = tokenizer.Tokenize(model.DecodedQuery, JObject.Parse(model.Parameters));

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var docs        = await _queryService.SearchAsync(context, parameterizedQuery);
                    model.Documents = docs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();
                }
                catch (Exception e)
                {
                    Logger.LogError("Error while executing query: {0}", e.Message);
                    ModelState.AddModelError(nameof(model.DecodedQuery), "Invalid query");
                }

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

            return(View(model));
        }
Beispiel #5
0
        public async Task <IActionResult> Query(AdminQueryViewModel model)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Forbid());
            }

            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 stopwatch = new Stopwatch();

            stopwatch.Start();

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

                var templateContext = _liquidTemplateManager.Context;
                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, _javaScriptEncoder);

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var luceneTopDocs      = await _queryService.SearchAsync(context, parameterizedQuery);

                    if (luceneTopDocs != null)
                    {
                        model.Documents = luceneTopDocs.TopDocs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();
                        model.Count     = luceneTopDocs.Count;
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Error while executing query");
                    ModelState.AddModelError(nameof(model.DecodedQuery), S["Invalid query : {0}", e.Message]);
                }

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

            return(View(model));
        }
Beispiel #6
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);
        }
Beispiel #7
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));
        }
Beispiel #8
0
        public async Task <AdminSearchResult> SearchContent(AdminSearchContext searchContext)
        {
            var searchResult = new AdminSearchResult();

            await _luceneIndexProvider.SearchAsync(searchContext.Index, async searcher =>
            {
                Query query;
                if (string.IsNullOrWhiteSpace(searchContext.SearchTerm))
                {
                    query = new MatchAllDocsQuery();
                }
                else
                {
                    var luceneVersion = LuceneSettings.DefaultVersion;
                    var analyzer      = new StandardAnalyzer(luceneVersion);

                    var multiFieldQuery = new MultiFieldQueryParser(luceneVersion, searchContext.IndexFieldsToSearch, analyzer);
                    query = multiFieldQuery.Parse(QueryParserBase.Escape(searchContext.SearchTerm));
                }

                searchContext.PageNumber -= 1;

                var start = searchContext.PageNumber * searchContext.PageSize;
                var end   = searchContext.PageNumber * searchContext.PageSize + searchContext.PageSize;

                var collector = TopScoreDocCollector.Create(end, true);
                var filter    = new BooleanFilter();

                if (searchContext.ContentTypes.Any())
                {
                    filter.Add(new FieldCacheTermsFilter("Content.ContentItem.ContentType", searchContext.ContentTypes), Occur.MUST);
                }

                if (searchContext.Filters != null && searchContext.Filters.Any())
                {
                    await _searchFilters.InvokeAsync(x => x.Filter(searchContext, filter), null);
                }

                if (filter.Any())
                {
                    searcher.Search(query, filter, collector);
                }
                else
                {
                    searcher.Search(query, collector);
                }

                var docs = collector.GetTopDocs(start, end);
                searchResult.TotalRecordCount = docs.TotalHits;

                var contentItemIds = docs.ScoreDocs.Select(hit =>
                {
                    var doc = searcher.Doc(hit.Doc);
                    return(doc.GetField("ContentItemId").GetStringValue());
                });

                searchResult.ContentItems = await _contentManager.GetAsync(contentItemIds);
            });

            return(searchResult);
        }