Advertisement
Guest User

FacetedQueryRunner

a guest
Oct 11th, 2011
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.64 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Lucene.Net.Index;
  5. using Lucene.Net.Search;
  6. using Raven.Abstractions.Data;
  7. using Raven.Abstractions.Extensions;
  8.  
  9. namespace Raven.Database.Queries
  10. {
  11.     public class FacetedQueryRunner
  12.     {
  13.         readonly DocumentDatabase database;
  14.  
  15.         public FacetedQueryRunner(DocumentDatabase database)
  16.         {
  17.             this.database = database;
  18.         }
  19.  
  20.         public IDictionary<string, IEnumerable<FacetValue>> GetFacets(string index, IndexQuery indexQuery, string facetSetupDoc)
  21.         {
  22.             var facetSetup = database.Get(facetSetupDoc, null);
  23.             if (facetSetup == null)
  24.                 return new Dictionary<string, IEnumerable<FacetValue>>(0);
  25.  
  26.             var facets = facetSetup.DataAsJson.JsonDeserialization<FacetSetup>().Facets;
  27.             var baseQuery = database.IndexStorage.GetLuceneQuery(index, indexQuery, database.IndexQueryTriggers);
  28.             var results = new Dictionary<string, IEnumerable<FacetValue>>();            
  29.  
  30.             IndexSearcher currentIndexSearcher;
  31.             using (database.IndexStorage.GetCurrentIndexSearcher(index, out currentIndexSearcher))
  32.             {
  33.                 foreach (var facet in facets)
  34.                 {
  35.                     switch (facet.Mode)
  36.                     {
  37.                         case FacetMode.Default:
  38.                             HandleTermsFacet(index, facet, baseQuery.Clone() as Query, currentIndexSearcher, results);
  39.                             break;
  40.                         case FacetMode.Ranges:
  41.                             HandleRangeFacet(index, facet, baseQuery.Clone() as Query, currentIndexSearcher, results);
  42.                             break;
  43.                         default:
  44.                             throw new ArgumentException("Could not understand " + facet.Mode);
  45.                     }
  46.                 }
  47.  
  48.             }
  49.  
  50.             return results;
  51.         }
  52.  
  53.         void HandleRangeFacet(string index, Facet facet, Query baseQuery, IndexSearcher currentIndexSearcher, Dictionary<string, IEnumerable<FacetValue>> results)
  54.         {
  55.             var rangeResults = new List<FacetValue>();
  56.             foreach (var range in facet.Ranges)
  57.             {
  58.                 ///TODO the built-in parser can't handle [NULL TO 100.0}, i.e. a mix of [ and }
  59.                 ///so we need to handle this ourselves (greater and less-than-or-equal)
  60.                 var rangeQuery = database.IndexStorage.GetLuceneQuery(index, new IndexQuery
  61.                 {
  62.                     Query = facet.Name + ":" + range
  63.                 },
  64.                 database.IndexQueryTriggers);
  65.  
  66.                 var joinedQuery = new BooleanQuery();
  67.                 joinedQuery.Add(baseQuery, BooleanClause.Occur.MUST);
  68.                 joinedQuery.Add(rangeQuery, BooleanClause.Occur.MUST);
  69.  
  70.                 var topDocs = currentIndexSearcher.Search(joinedQuery, 1);
  71.  
  72.                 if (topDocs.TotalHits > 0)
  73.                 {
  74.                     rangeResults.Add(new FacetValue
  75.                     {
  76.                         Count = topDocs.TotalHits,
  77.                         Range = range
  78.                     });
  79.                 }
  80.             }
  81.  
  82.             results[facet.Name] = rangeResults;
  83.         }
  84.  
  85.         void HandleTermsFacet(string index, Facet facet, Query baseQuery, IndexSearcher currentIndexSearcher, Dictionary<string, IEnumerable<FacetValue>> results)
  86.         {
  87.             var terms = GetFacetTerms(index, facet);
  88.             var termResults = new List<FacetValue>();
  89.  
  90.             foreach (var term in terms)
  91.             {
  92.                 var termQuery = new TermQuery(new Term(facet.Name, term));
  93.  
  94.                 var joinedQuery = new BooleanQuery();
  95.                 joinedQuery.Add(baseQuery, BooleanClause.Occur.MUST);
  96.                 joinedQuery.Add(termQuery, BooleanClause.Occur.MUST);
  97.  
  98.                 var topDocs = currentIndexSearcher.Search(joinedQuery, 1);
  99.                 if (topDocs.TotalHits > 0)
  100.                 {
  101.                     termResults.Add(new FacetValue
  102.                     {
  103.                         Count = topDocs.TotalHits,
  104.                         Range = term
  105.                     });
  106.                 }
  107.             }
  108.  
  109.             results[facet.Name] = termResults;
  110.         }
  111.  
  112.         IEnumerable<string> GetFacetTerms(string index, Facet facet)
  113.         {
  114.             if (facet.Ranges == null || facet.Ranges.Count == 0)
  115.             {
  116.                 return database.ExecuteGetTermsQuery(index, facet.Name, null, database.Configuration.MaxPageSize);
  117.             }
  118.             else
  119.             {
  120.                 return facet.Ranges;
  121.             }
  122.         }
  123.     }
  124. }
  125.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement