2012-04-20 27 views
6

Tôi đang xem xét RavenDb để thực hiện một kịch bản 'tìm kiếm tiên tiến'.
Tôi phải đối phó với phân loại phân cấp phức tạp và các khía cạnh được chia sẻ trên các nhánh khác nhau của cây trong khi hỗ trợ tìm kiếm toàn văn và tất cả các tính năng cơ bản khác.Phân loại theo cấp bậc trong Tìm kiếm Mặt bằng RavenDb/Lucene?

Có tài nguyên nào ở đó tài liệu hướng dẫn cách thực hiện việc này bằng API RavenDb không?

giấy Insanely phức tạp về đề tài này: Beyond Basic Faceted Search
Solr của cách: HierarchicalFaceting

Trả lời

5

Cuối cùng ..

using System.Collections.Generic; 
using System.Linq; 
using NUnit.Framework; 
using Raven.Abstractions.Data; 
using Raven.Client; 
using Raven.Client.Document; 
using Raven.Client.Indexes; 
using Raven.Client.Linq; 

namespace Prototype.Search.Tests 
{ 
    [TestFixture] 
    public class HierarchicalFaceting 
    { 
     // 
     // Document definition 
     // 
     public class Doc 
     { 
      public Doc() 
      { 
       Categories = new List<string>(); 
      } 

      public int Id { get; set; } 
      public List<string> Categories { get; set; } 
     } 

     // 
     // Data sample 
     // 
     public IEnumerable<Doc> GetDocs() 
     { 
      yield return new Doc { Id = 1, Categories = new List<string> { "0/NonFic", "1/NonFic/Law"} }; 
      yield return new Doc { Id = 2, Categories = new List<string> { "0/NonFic", "1/NonFic/Sci" } }; 
      yield return new Doc { Id = 3, Categories = new List<string> { "0/NonFic", "1/NonFic/Hist", "1/NonFic/Sci", "2/NonFic/Sci/Phys" } }; 
     } 

     // 
     // The index 
     // 
     public class DocByCategory : AbstractIndexCreationTask<Doc, DocByCategory.ReduceResult> 
     { 
      public class ReduceResult 
      { 
       public string Category { get; set; } 
      } 

      public DocByCategory() 
      { 
       Map = docs => 
         from d in docs 
         from c in d.Categories 
         select new 
           { 
            Category = c 
           }; 
      } 
     } 

     // 
     // FacetSetup 
     // 
     public FacetSetup GetDocFacetSetup() 
     { 
      return new FacetSetup 
         { 
          Id = "facets/Doc", 
          Facets = new List<Facet> 
             { 
              new Facet 
               { 
                Name = "Category" 
               } 
             } 
         }; 
     } 

     [SetUp] 
     public void SetupDb() 
     { 
      IDocumentStore store = new DocumentStore() 
      { 
       Url = "http://localhost:8080" 
      }; 
      store.Initialize(); 
      IndexCreation.CreateIndexes(typeof(HierarchicalFaceting).Assembly, store); 

      var session = store.OpenSession(); 
      session.Store(GetDocFacetSetup()); 
      session.SaveChanges(); 

      store.Dispose(); 
     } 

     [Test] 
     [Ignore] 
     public void DeleteAll() 
     { 
      IDocumentStore store = new DocumentStore() 
      { 
       Url = "http://localhost:8080" 
      }; 
      store.Initialize(); 

      store.DatabaseCommands.DeleteIndex("Raven/DocByCategory"); 
      store.DatabaseCommands.DeleteByIndex("Raven/DocumentsByEntityName", new IndexQuery()); 

      store.Dispose(); 
     } 

     [Test] 
     [Ignore] 
     public void StoreDocs() 
     { 
      IDocumentStore store = new DocumentStore() 
      { 
       Url = "http://localhost:8080" 
      }; 
      store.Initialize(); 

      var session = store.OpenSession(); 

      foreach (var doc in GetDocs()) 
      { 
       session.Store(doc); 
      } 

      session.SaveChanges(); 
      session.Dispose(); 
      store.Dispose(); 
     } 

     [Test] 
     public void QueryDocsByCategory() 
     { 
      IDocumentStore store = new DocumentStore() 
      { 
       Url = "http://localhost:8080" 
      }; 
      store.Initialize(); 

      var session = store.OpenSession(); 

      var q = session.Query<DocByCategory.ReduceResult, DocByCategory>() 
       .Where(d => d.Category == "1/NonFic/Sci") 
       .As<Doc>(); 

      var results = q.ToList(); 
      var facetResults = q.ToFacets("facets/Doc").ToList(); 

      session.Dispose(); 
      store.Dispose(); 
     } 

     [Test] 
     public void GetFacets() 
     { 
      IDocumentStore store = new DocumentStore() 
      { 
       Url = "http://localhost:8080" 
      }; 
      store.Initialize(); 

      var session = store.OpenSession(); 

      var q = session.Query<DocByCategory.ReduceResult, DocByCategory>() 
       .Where(d => d.Category.StartsWith("1/NonFic")) 
       .As<Doc>(); 

      var results = q.ToList(); 
      var facetResults = q.ToFacets("facets/Doc").ToList(); 

      session.Dispose(); 
      store.Dispose(); 
     } 
    } 
} 
+0

cảm ơn mã, hoạt động như một khoe! Cách tiếp cận tốt nhất khi Doc có trường tiêu đề là gì và tôi muốn lọc các khía cạnh dựa trên thực tế là Tiêu đề này có chứa một chuỗi nhất định không? –

1

tôi sẽ xử lý phần cây tìm kiếm này sử dụng tinh khiết Lucene vì tốc độ của. 2 phương pháp tiếp cận là phương pháp liên kết cha-con và phương pháp liệt kê đường dẫn/'Dewey Decimal'.

Cha mẹ-con là cách tất cả chúng ta đã học để triển khai danh sách được liên kết trở lại trong lớp thuật toán. Nó rất dễ dàng để cập nhật, nhưng các truy vấn yêu cầu truy cập mỗi nút (bạn không thể trực tiếp từ cha mẹ đến cháu của nó, chẳng hạn). Cho rằng bạn cần phải truy cập tất cả tổ tiên của một nút nào đó để có được tất cả các thuộc tính (vì ý tưởng là chia sẻ các thuộc tính), phải truy cập tất cả các tổ tiên có thể là một điểm tranh luận.

How to store tree data in a Lucene/Solr/Elasticsearch index or a NoSQL db? bao gồm phương pháp liệt kê đường dẫn/phương pháp 'Dewey Decimal'.

Hoặc cách tiếp cận có thể xử lý một hệ thống phân cấp phức tạp tùy ý, miễn là nó là một hệ thống phân cấp thực sự (tức là đồ thị theo chu kỳ trực tiếp (D.A.G.)).

+1

Đầu tiên, cảm ơn bạn đã dành thời gian. Tuy nhiên, tôi cần phải làm rõ một điều .. dữ liệu của tôi - được lưu trữ trong Esent - không phải là thứ bậc; Các khía cạnh khác nhau của dữ liệu của tôi là phân cấp. Trong ngôn ngữ Lucene, tôi tin rằng chúng được gọi là _terms_. Vì vậy, các thuật ngữ chính họ là phân cấp. Tham khảo bài báo tôi đã liên kết ở trên trang 36 và xem biểu đồ ở góc trên cùng bên phải. Sử dụng cách tiếp cận của bạn, tôi sẽ thiết kế một chỉ mục trong Lucene để truy vấn dữ liệu phân cấp nhưng tôi đang tìm kiếm các tài nguyên đơn giản và sạch để áp dụng khái niệm này cho các thuật ngữ của Lucene: phân loại phân cấp. – maxbeaudoin

1

tôi cố định nó rồi.

tôi tạo ra các chỉ số như sau:

public class ProductByCategory : AbstractIndexCreationTask<Product, ProductByCategory.ReduceResult> 
{ 
    public class ReduceResult 
    { 
     public string Category { get; set; } 
     public string Title { get; set; } 
    } 

    public ProductByCategory() 
    { 
     Map = products => 
       from p in products 
       from c in p.Categories 
       select new 
       { 
        Category = c, 
        Title = p.Title 
       }; 
     Stores.Add(x => x.Title, FieldStorage.Yes); 
     Indexes.Add(x => x.Title, FieldIndexing.Analyzed); 
    } 
} 

Và tôi truy vấn nó thích:

var q = session.Query<ProductByCategory.ReduceResult, ProductByCategory>().Search(x => x.Title, "Sony") 
.Where(r => r.Category.StartsWith("1/beeld en geluid")).As<Product>(); 

var facetResults = q.ToFacets("facets/ProductCategory"); 
Các vấn đề liên quan