public SearchResultSet Search(string query, int offset = 0, int count = 20)
        {
            using (TraceSources.ContentSearcherSource.TraceActivity("Search [{1}-{2}]: {0}", query, offset, offset + count))
            {
                SearchResultSet ret = new SearchResultSet();

                //Query q = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "body", this._analyzer).Parse(query);

                string[] rawTerms = query.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);


                BooleanQuery titleQuery = new BooleanQuery();
                BooleanQuery summaryQuery = new BooleanQuery();
                BooleanQuery contentQuery = new BooleanQuery();

                for (int i = 0; i < rawTerms.Length; i++)
                {
                    string rawTerm = rawTerms[i];
                    BooleanClause.Occur occur;
                    if (rawTerms[i].StartsWith("-"))
                    {
                        rawTerm = rawTerm.Substring(1);
                        occur = BooleanClause.Occur.MUST_NOT;
                    }
                    else
                        occur = BooleanClause.Occur.MUST;

                    titleQuery.Add(new TermQuery(new Term("title", rawTerm)), occur);

                    summaryQuery.Add(new TermQuery(new Term("summary", rawTerm)), occur);

                    contentQuery.Add(new TermQuery(new Term("content", rawTerm)), occur);
                }

                BooleanQuery q = new BooleanQuery();

                titleQuery.SetBoost(8f);
                contentQuery.SetBoost(0.7f);
                
                q.Add(titleQuery, BooleanClause.Occur.SHOULD);
                q.Add(summaryQuery, BooleanClause.Occur.SHOULD);
                q.Add(contentQuery, BooleanClause.Occur.SHOULD);

                TopDocs docs = this._indexSearcher.Search(titleQuery, offset + count);

                if (docs.ScoreDocs.Length < offset)
                    throw new ArgumentOutOfRangeException("offset", "Offset is smaller than result count!");

                ret.HitCount = docs.TotalHits;

                ret.Results = new SearchResult[Math.Min(docs.ScoreDocs.Length - offset, count)];

                for (int i = 0; i < ret.Results.Length; i++)
                {
                    var scoreDoc = docs.ScoreDocs[offset + i];

                    Document doc = this._indexSearcher.Doc(scoreDoc.doc);

                    ret.Results[i] = new SearchResult
                                         {
                                             AssetId = AssetIdentifier.Parse(doc.GetField("aid").StringValue()),
                                             Title = doc.GetField("title").StringValue(),
                                             Url = new Uri(doc.GetField("uri").StringValue(), UriKind.RelativeOrAbsolute),
                                             Blurb = doc.GetField("summary").StringValue(),
                                         };
                }

                return ret;
            }
        }
Beispiel #2
0
        public SearchResultSet Search(string query, int offset = 0, int count = 20)
        {
            using (TraceSources.ContentSearcherSource.TraceActivity("Search [{1}-{2}]: {0}", query, offset, offset + count))
            {
                SearchResultSet ret = new SearchResultSet();

                //Query q = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "body", this._analyzer).Parse(query);

                string[] rawTerms = query.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                BooleanQuery titleQuery   = new BooleanQuery();
                BooleanQuery summaryQuery = new BooleanQuery();
                BooleanQuery contentQuery = new BooleanQuery();

                for (int i = 0; i < rawTerms.Length; i++)
                {
                    string rawTerm = rawTerms[i];
                    Occur  occur;
                    if (rawTerms[i].StartsWith("-"))
                    {
                        rawTerm = rawTerm.Substring(1);
                        occur   = Occur.MUST_NOT;
                    }
                    else
                    {
                        occur = Occur.MUST;
                    }

                    titleQuery.Add(new TermQuery(new Term("title", rawTerm)), occur);

                    summaryQuery.Add(new TermQuery(new Term("summary", rawTerm)), occur);

                    contentQuery.Add(new TermQuery(new Term("content", rawTerm)), occur);
                }

                BooleanQuery q = new BooleanQuery();

                titleQuery.Boost   = 8f;
                contentQuery.Boost = 0.7f;

                q.Add(titleQuery, Occur.SHOULD);
                q.Add(summaryQuery, Occur.SHOULD);
                q.Add(contentQuery, Occur.SHOULD);

                TopDocs docs = this._indexSearcher.Search(titleQuery, offset + count);

                if (docs.ScoreDocs.Length < offset)
                {
                    throw new ArgumentOutOfRangeException("offset", "Offset is smaller than result count!");
                }

                ret.HitCount = docs.TotalHits;

                ret.Results = new SearchResult[Math.Min(docs.ScoreDocs.Length - offset, count)];

                for (int i = 0; i < ret.Results.Length; i++)
                {
                    var scoreDoc = docs.ScoreDocs[offset + i];

                    Document doc = this._indexSearcher.Doc(scoreDoc.Doc);

                    ret.Results[i] = new SearchResult
                    {
                        AssetId = AssetIdentifier.Parse(doc.GetField("aid").StringValue),
                        Title   = doc.GetField("title").StringValue,
                        Url     = new Uri(doc.GetField("uri").StringValue, UriKind.RelativeOrAbsolute),
                        Blurb   = doc.GetField("summary").StringValue,
                    };
                }

                return(ret);
            }
        }
        public SearchResultSet Search(string query, int offset = 0, int count = 20, bool includeRawData = false)
        {
            using (TraceSources.ContentSearcherSource.TraceActivity("Search [{1}-{2}]: {0}", query, offset, offset + count))
            {
                SearchResultSet ret = new SearchResultSet();

                string[] rawTerms = query.ToLowerInvariant().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                BooleanQuery termQueries = new BooleanQuery();

                // TODO figure out how to build a decent query

                for (int i = 0; i < rawTerms.Length; i++)
                {
                    string term = rawTerms[i];

                    Occur occur;
                    if (rawTerms[i].StartsWith("-"))
                    {
                        term = term.Substring(1);
                        occur = Occur.MUST_NOT;
                    }
                    else
                        occur = Occur.MUST;

                    if (term.StartsWith("type:", StringComparison.InvariantCultureIgnoreCase))
                    {
                        term = term.Substring("type:".Length);
                        termQueries.Add(new TermQuery(new Term("type", term)), occur);
                    }
                    else if (StringComparer.InvariantCultureIgnoreCase.Equals(term, "special:all"))
                    {
                        termQueries.Add(new MatchAllDocsQuery(), occur);
                    }
                    else
                    {
                        BooleanQuery termQuery = new BooleanQuery();
                        termQuery.Add(new PrefixQuery(new Term("camelCase", term)) { Boost = 6f }, Occur.SHOULD);
                        termQuery.Add(new PrefixQuery(new Term("name", term)) { Boost = 5f }, Occur.SHOULD);
                        termQuery.Add(new TermQuery(new Term("title", term)) { Boost = 4f }, Occur.SHOULD);
                        termQuery.Add(new TermQuery(new Term("summary", term)), Occur.SHOULD);
                        termQuery.Add(new TermQuery(new Term("content", term)) { Boost = 0.5f }, Occur.SHOULD);
                        termQueries.Add(termQuery, occur);
                    }
                }

                TopDocs docs = this._indexSearcher.Search(termQueries, offset + count);

                if (docs.ScoreDocs.Length < offset)
                    throw new ArgumentOutOfRangeException("offset", "Offset is smaller than result count!");

                ret.HitCount = docs.TotalHits;

                ret.Results = new SearchResult[Math.Min(docs.ScoreDocs.Length - offset, count)];

                for (int i = 0; i < ret.Results.Length; i++)
                {
                    ScoreDoc scoreDoc = docs.ScoreDocs[offset + i];

                    Document doc = this._indexSearcher.Doc(scoreDoc.Doc);

                    var jsonPath = doc.GetField("path").StringValue;
                    var jsonArray = JArray.Parse(jsonPath);
                    var fragments = jsonArray.Cast<JObject>()
                                             .Select(f => new PathFragment
                                                          {
                                                              AssetId = AssetIdentifier.Parse(f["assetId"].Value<string>()),
                                                              Name = f["name"].Value<string>(),
                                                              Url = new Uri(f["url"].Value<string>(), UriKind.RelativeOrAbsolute),
                                                              Blurb = f["blurb"].Value<string>(),
                                                              Type = f["type"].Value<string>(),
                                                          }).ToArray();

                    ret.Results[i] = new SearchResult
                                         {
                                             AssetId = AssetIdentifier.Parse(doc.GetField("aid").StringValue),
                                             Name = doc.GetField("name").StringValue,
                                             Title = doc.GetField("title").StringValue,
                                             Url = new Uri(doc.GetField("uri").StringValue, UriKind.RelativeOrAbsolute),
                                             Blurb = doc.GetField("summary").StringValue,
                                             RawDocument = includeRawData ? this.GetRawData(doc, scoreDoc.Doc).ToArray() : null,
                                             Type = doc.GetField("type").StringValue,
                                             Flags = doc.GetFields("typeFlag").Select(f => f.StringValue).ToArray(),
                                             Path = fragments
                                         };
                }

                return ret;
            }
        }