private SearchResultSet generalSearch(string searchString) { var defaultField = ALL; using var index = getIndex(); using var searcher = new IndexSearcher(index); using var analyzer = new StandardAnalyzer(Version); var query = analyzer.GetQuery(defaultField, searchString); // lucene doesn't allow only negations. eg this returns nothing: // -tags:hidden // work arounds: https://kb.ucla.edu/articles/pure-negation-query-in-lucene // HOWEVER, doing this to any other type of query can cause EVERYTHING to be a match unless "Occur" is carefully set // this should really check that all leaf nodes are MUST_NOT if (query is BooleanQuery boolQuery) { var occurs = getOccurs_recurs(boolQuery); if (occurs.Any() && occurs.All(o => o == Occur.MUST_NOT)) { boolQuery.Add(new MatchAllDocsQuery(), Occur.MUST); } } var docs = searcher .Search(query, searcher.MaxDoc + 1) .ScoreDocs .Select(ds => new ScoreDocExplicit(searcher.Doc(ds.Doc), ds.Score)) .ToList(); var queryString = query.ToString(); Serilog.Log.Logger.Debug("query: {@DebugInfo}", new { queryString }); return(new SearchResultSet(queryString, docs)); }