Исключить макросы из поиска в umbraco

Я столкнулся с проблемой при настройке поисковой системы Lucene в umbraco. Я пытаюсь выполнить поиск по данным, хранящимся в индексе по умолчанию, созданном Umbraco. Метод поиска ниже:

        private DictionaryResult GetRowContent(
        Lucene.Net.Highlight.Highlighter highlighter,
        Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer
        ,Lucene.Net.Documents.Document doc1, string criteria)
    {
        JavaScriptSerializer jsScriptSerializer = new JavaScriptSerializer();
        DictionaryResult controls = new DictionaryResult();
        Lucene.Net.Analysis.TokenStream stream = analyzer.TokenStream("", new StringReader(doc1.Get("bodyContent")));
        dynamic rowContentHtmlDocument = JObject.Parse(((JValue)doc1.Get("bodyContent")).ToString(CultureInfo.CurrentCulture));
        foreach (dynamic section in rowContentHtmlDocument.sections)
        {
            foreach (var row in section.rows)
            {
                foreach (var area in row.areas)
                {
                    foreach (var control in area.controls)
                    {
                        if (control != null && control.editor != null) // && control.editor.view != null)
                        {
                            JObject rowContentHtml = null;
                            try
                            {
                                rowContentHtml = JObject.Parse(((JContainer)control)["value"].ToString());
                            }
                            catch (Exception e)
                            {
                            }
                            if (rowContentHtml != null)
                            {
                                try
                                {
                                    var macroParamsDictionary = JObject.Parse(((JContainer)rowContentHtml)["macroParamsDictionary"].ToString());
                                    var documentText = macroParamsDictionary.GetValue("dokument");
                                    if (documentText != null)
                                    {
                                        var document = documentText.ToString().Replace(""", "\"");
                                        dynamic documents = jsScriptSerializer.Deserialize<dynamic>(document);
                                        foreach (Dictionary<string, object> doc in documents)
                                        {
                                            if (doc.ContainsKey("FileName") && doc.ContainsKey("DocumentId"))
                                            {
                                                if (doc["FileName"].ToString().Length > 0 && 
                                                    doc["FileName"].ToString().ToLower().Contains(criteria.ToLower()))
                                                {
                                                    controls.Add(new RowResult()
                                                    {
                                                        Type = 0,
                                                        Object = new Document()
                                                        {
                                                            DocumentName = doc["FileName"].ToString(),//highlighter.GetBestFragments(stream, doc["FileName"].ToString(), 1, "..."),
                                                            DocId = Guid.Parse(doc["DocumentId"].ToString())
                                                        } // StringBuilder(@"<a href=" + Url.Action("DownloadDocument", "Document", new { DocumentId = doc["DocumentId"] }) + "> " + @doc["FileName"] + "</a>").ToString()
                                                    }
                                                    );
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                }
                            }
                            else
                            {
                                var text = HtmlRemoval.StripTagsRegex(((JContainer)control)["value"].ToString()).Replace("ë", "e").Replace("ç", "c");
                                var textResultFiltered =  highlighter.GetBestFragments(stream,doc1.Get("bodyContent"), 5, "...");
                                controls.Add(new RowResult()
                                {
                                    Type = 1,
                                    Object = textResultFiltered
                                });
                            }
                        }
                    }
                }
            }
        }
        return controls;
    }

Здесь я пытаюсь отфильтровать макро-документы из простого HTML-контента и по-разному отображать. Но в конце этой части

var text = HtmlRemoval.StripTagsRegex(((JContainer)control)["value"].ToString()).Replace("ë", "e").Replace("ç", "c");
                            var textResultFiltered =  highlighter.GetBestFragments(stream,doc1.Get("bodyContent"), 5, "...");
                            controls.Add(new RowResult()
                            {
                                Type = 1,
                                Object = textResultFiltered
                            });

это включает макрос в поиске. В результате я получаю свойство документов, но html-контент hightlighted имеет макрос-содержимое, как показано ниже:

6th Edition V413HAV.pdf","FileContent"... Framework 6th Edition V413HAV.pdf","... with Java 8 - 1st Edition (2015) - Copy.pdf"... 4.5 Framework 6th Edition V413HAV.pdf","... And The NET 4.5 Framework 6th Edition V413HAV.pdf" which is coming from Json data of the macro. Any idea how to exclude the macros from searching or to customize the hmtl content not to search on specific macro ? Thanks in advance. 

Я использую эту ссылку для создания Hightlighter и т. Д.... Ссылка на пример Lucene

Есть идеи, как запретить поиск макросов или исключить их из выделенного содержимого?

3 ответа

Это выглядит слишком сложно, чтобы быть правым, если вы просто делаете регулярный поиск. Знаете ли вы, что у Umbraco есть своя собственная "версия" Lucene под названием Examine? Он встроен в Umbraco и не требует особых настроек для запуска стандартного поиска: https://our.umbraco.org/documentation/reference/searching/examine/

Я никогда не видел макросов или разметки JSON в результатах поиска с помощью Examine, так что, возможно, попробуйте?

Я попытался использовать Examine, а также ниже:

SearchQuery = string.Format("+{0}:{1}~", SearchField, criteria);
var Criteria = ExamineManager.Instance
                    .SearchProviderCollection["ExternalSearcher"]
                    .CreateSearchCriteria();
var crawl = Criteria.GroupedOr(new string[] { "bodyContent", "nodeName" }, criteria)
                    .Not()
                    .Field("umbracoNaviHide", "1")
                    .Not()
                    .Field("nodeTypeAlias", "Image")
                    .Compile();
IEnumerable<Examine.SearchResult> SearchResults1 = ExamineManager.Instance
                    .SearchProviderCollection["ExternalSearcher"]
                    .Search(crawl);

Я использовал два метода для выделения текста, как показано ниже, но эти методы не совсем эффективны!!! У меня было несколько ссылок без текста вообще.

        public string GetHighlight(string value, string highlightField, BaseLuceneSearcher searcher, string luceneRawQuery)
    {
        var query = GetQueryParser(highlightField).Parse(luceneRawQuery);
        var scorer = new QueryScorer(searcher.GetSearcher().Rewrite(query));

        var highlighter = new Highlighter(HighlightFormatter, scorer);

        var tokenStream = HighlightAnalyzer.TokenStream(highlightField, new StringReader(value));
        return highlighter.GetBestFragments(tokenStream, value, MaxNumHighlights, Separator);
    }
    protected QueryParser GetQueryParser(string highlightField)
    {
        if (!QueryParsers.ToString().Contains(highlightField))
        {
            var temp = new QueryParser(_luceneVersion, highlightField, HighlightAnalyzer);
            return temp;
        }
        return null;
    }

Если у вас есть образец с подсветкой в ​​Examine, который был бы достаточно эффективным, я был бы признателен.

Вы можете легко использовать Examine. Вам нужно только выбрать нужный поставщик поиска (config/ExamineSettings.config), который позволит вам выбрать, хотите ли вы избежать неопубликованного и защищенного контента. Тогда вам нужно всего лишь сделать что-то вроде следующего фрагмента кода, где вы можете выбрать поля, которые вы хотите найти, или Dact Types, которые вы не хотите избегать, например.

string term = "test"

var criteria = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"].CreateSearchCriteria();
var crawl = criteria.GroupedOr(new string[] { "nodeName", "pageTitle", "metaDescription", "metaKeywords" }, term)
                .Not().Field("nodeTypeAlias", "GlobalSettings")
                .Not().Field("nodeTypeAlias", "Error")
                .Not().Field("nodeTypeAlias", "File")
                .Not().Field("nodeTypeAlias", "Folder")
                .Not().Field("nodeTypeAlias", "Image")
                .Not().Field("excludeFromSearch", "1")
                .Compile();

 ISearchResults SearchResults = ExamineManager.Instance
                .SearchProviderCollection["ExternalSearcher"]
                .Search(crawl);

 IList<JsonSearchResult> results = new List<JsonSearchResult>();

Надеюсь, что это имеет смысл.

Другие вопросы по тегам