使用RavenDb/Lucene的分面搜索中的层次分类法?

使用RavenDb/Lucene的分面搜索中的层次分类法?,lucene,ravendb,faceted-search,Lucene,Ravendb,Faceted Search,我正在考虑RavenDb实施“高级分面搜索”方案。 我必须处理复杂的层次分类法和跨树的不同分支的共享方面,同时支持全文搜索和所有其他基本功能 是否有任何资源记录了如何使用RavendBAPI实现这一点 关于该主题的极其复杂的论文: Solr's way:为了速度起见,我会使用纯Lucene处理这部分的树搜索。2种方法是父子链接法和路径枚举/杜威十进制法 父子关系是我们在算法类中学习实现链表的方式。更新很容易,但查询需要访问每个节点(例如,您无法直接从父节点访问其曾孙节点)。考虑到无论如何都需要访

我正在考虑RavenDb实施“高级分面搜索”方案。
我必须处理复杂的层次分类法和跨树的不同分支的共享方面,同时支持全文搜索和所有其他基本功能

是否有任何资源记录了如何使用RavendBAPI实现这一点

关于该主题的极其复杂的论文:

Solr's way:

为了速度起见,我会使用纯Lucene处理这部分的树搜索。2种方法是父子链接法和路径枚举/杜威十进制法

父子关系是我们在算法类中学习实现链表的方式。更新很容易,但查询需要访问每个节点(例如,您无法直接从父节点访问其曾孙节点)。考虑到无论如何都需要访问节点的所有祖先才能获得所有属性(因为这样做的目的是共享属性),因此访问所有祖先可能是一个没有实际意义的问题

介绍路径枚举/“Dewey Decimal”方法

任何一种方法都可以处理任意复杂的层次结构,只要它是真实的层次结构(即有向无环图(D.a.G.)。

最后

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();
        }
    }
}
使用System.Collections.Generic;
使用System.Linq;
使用NUnit.Framework;
使用Raven.Abstractions.Data;
使用Raven.Client;
使用Raven.Client.Document;
使用Raven.Client.index;
使用Raven.Client.Linq;
命名空间Prototype.Search.Tests
{
[测试夹具]
公共类层次刻面
{
//
//文件定义
//
公共类文件
{
公共文件()
{
类别=新列表();
}
公共int Id{get;set;}
公共列表类别{get;set;}
}
//
//数据样本
//
公共IEnumerable GetDocs()
{
生成返回新文档{Id=1,Categories=newlist{“0/NonFic”,“1/NonFic/Law”};
生成返回新文档{Id=2,类别=新列表{“0/NonFic”,“1/NonFic/Sci”};
产生返回新文档{Id=3,类别=新列表{“0/NonFic”,“1/NonFic/Hist”,“1/NonFic/Sci”,“2/NonFic/Sci/Phys”};
}
//
//索引
//
公共类DocByCategory:AbstractIndexCreationTask
{
公共类ReduceResult
{
公共字符串类别{get;set;}
}
公共DocByCategory()
{
Map=docs=>
从文档中的d开始
d类中的c类
选择新的
{
类别=c
};
}
}
//
//面设置
//
公共FacetSetup GetDocFacetSetup()
{
返回新的FacetSetup
{
Id=“facets/Doc”,
Facets=新列表
{
新方面
{
Name=“类别”
}
}
};
}
[设置]
public void SetupDb()
{
IDocumentStore=新文档库()
{
Url=”http://localhost:8080"
};
store.Initialize();
CreateIndexes(typeof(HierarchycalFaceting).Assembly,store);
var session=store.OpenSession();
session.Store(GetDocFacetSetup());
session.SaveChanges();
store.Dispose();
}
[测试]
[忽略]
public void DeleteAll()
{
IDocumentStore=新文档库()
{
Url=”http://localhost:8080"
};
store.Initialize();
store.DatabaseCommands.DeleteIndex(“Raven/DocByCategory”);
store.DatabaseCommands.DeleteByIndex(“Raven/DocumentsByEntityName”,new IndexQuery());
store.Dispose();
}
[测试]
[忽略]
公共文件
{
IDocumentStore=新文档库()
{
Url=”http://localhost:8080"
};
store.Initialize();
var session=store.OpenSession();
foreach(GetDocs()中的var doc)
{
会话存储(doc);
}
session.SaveChanges();
session.Dispose();
store.Dispose();
}
[测试]
公共无效QueryDocsByCategory()
{
IDocumentStore=新文档库()
{
Url=”http://localhost:8080"
};
store.Initialize();
var session=store.OpenSession();
var q=session.Query()
其中(d=>d.类别==“1/NonFic/Sci”)
.As();
var结果=q.ToList();
var facetResults=q.ToFacets(“facets/Doc”).ToList();
session.Dispose();
store.Dispose();
}
[测试]
public void GetFacets()
{
IDocumentStore=新文档库()
{
Url=”http://localhost:8080"
};
store.Initialize();
var session=store.OpenSession();
var q=session.Query()
.Where(d=>d.Category.StartsWith(“1/NonFic”))
.As();
var结果=q.ToList();
var facetResults=q.ToFacets(“facets/Doc”).ToList();
session.Dispose()
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);
    }
}
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");