Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Lucene.Net.Index;
- using Lucene.Net.Search;
- using Raven.Abstractions.Data;
- using Raven.Abstractions.Extensions;
- namespace Raven.Database.Queries
- {
- public class FacetedQueryRunner
- {
- readonly DocumentDatabase database;
- public FacetedQueryRunner(DocumentDatabase database)
- {
- this.database = database;
- }
- public IDictionary<string, IEnumerable<FacetValue>> GetFacets(string index, IndexQuery indexQuery, string facetSetupDoc)
- {
- var facetSetup = database.Get(facetSetupDoc, null);
- if (facetSetup == null)
- return new Dictionary<string, IEnumerable<FacetValue>>(0);
- var facets = facetSetup.DataAsJson.JsonDeserialization<FacetSetup>().Facets;
- var baseQuery = database.IndexStorage.GetLuceneQuery(index, indexQuery, database.IndexQueryTriggers);
- var results = new Dictionary<string, IEnumerable<FacetValue>>();
- IndexSearcher currentIndexSearcher;
- using (database.IndexStorage.GetCurrentIndexSearcher(index, out currentIndexSearcher))
- {
- foreach (var facet in facets)
- {
- switch (facet.Mode)
- {
- case FacetMode.Default:
- HandleTermsFacet(index, facet, baseQuery.Clone() as Query, currentIndexSearcher, results);
- break;
- case FacetMode.Ranges:
- HandleRangeFacet(index, facet, baseQuery.Clone() as Query, currentIndexSearcher, results);
- break;
- default:
- throw new ArgumentException("Could not understand " + facet.Mode);
- }
- }
- }
- return results;
- }
- void HandleRangeFacet(string index, Facet facet, Query baseQuery, IndexSearcher currentIndexSearcher, Dictionary<string, IEnumerable<FacetValue>> results)
- {
- var rangeResults = new List<FacetValue>();
- foreach (var range in facet.Ranges)
- {
- ///TODO the built-in parser can't handle [NULL TO 100.0}, i.e. a mix of [ and }
- ///so we need to handle this ourselves (greater and less-than-or-equal)
- var rangeQuery = database.IndexStorage.GetLuceneQuery(index, new IndexQuery
- {
- Query = facet.Name + ":" + range
- },
- database.IndexQueryTriggers);
- var joinedQuery = new BooleanQuery();
- joinedQuery.Add(baseQuery, BooleanClause.Occur.MUST);
- joinedQuery.Add(rangeQuery, BooleanClause.Occur.MUST);
- var topDocs = currentIndexSearcher.Search(joinedQuery, 1);
- if (topDocs.TotalHits > 0)
- {
- rangeResults.Add(new FacetValue
- {
- Count = topDocs.TotalHits,
- Range = range
- });
- }
- }
- results[facet.Name] = rangeResults;
- }
- void HandleTermsFacet(string index, Facet facet, Query baseQuery, IndexSearcher currentIndexSearcher, Dictionary<string, IEnumerable<FacetValue>> results)
- {
- var terms = GetFacetTerms(index, facet);
- var termResults = new List<FacetValue>();
- foreach (var term in terms)
- {
- var termQuery = new TermQuery(new Term(facet.Name, term));
- var joinedQuery = new BooleanQuery();
- joinedQuery.Add(baseQuery, BooleanClause.Occur.MUST);
- joinedQuery.Add(termQuery, BooleanClause.Occur.MUST);
- var topDocs = currentIndexSearcher.Search(joinedQuery, 1);
- if (topDocs.TotalHits > 0)
- {
- termResults.Add(new FacetValue
- {
- Count = topDocs.TotalHits,
- Range = term
- });
- }
- }
- results[facet.Name] = termResults;
- }
- IEnumerable<string> GetFacetTerms(string index, Facet facet)
- {
- if (facet.Ranges == null || facet.Ranges.Count == 0)
- {
- return database.ExecuteGetTermsQuery(index, facet.Name, null, database.Configuration.MaxPageSize);
- }
- else
- {
- return facet.Ranges;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement