没有其他方法可以获取索引的术语。要获取条款,客户端 api 提供的唯一功能记录在 here。
因此,如果您必须通过某些属性值过滤术语,则必须将 where 子句移至索引定义。
如果预先知道要过滤的值,则可以使用继承自AbstractIndexCreationTask的静态索引定义类
public class FullTextIndex : AbstractIndexCreationTask<Topic, SearchQueryResult>
{
public FullTextIndex()
{
Map = topics => from topic in topics
where topic.CompanyName == "TheFirm"
from content in topic.Content
select new
{
topic.CompanyName,
Query = new object[]
{
content.Title,
content.Description,
content.Article
}
};
Analyzers.Add(x => x.Query, typeof(OurCustomHtmlStandardAnalyzer).AssemblyQualifiedName);
Indexes.Add(x => x.Query, FieldIndexing.Analyzed);
Stores.Add(x => x.Query, FieldStorage.Yes);
}
}
注意 Map 部分中的 where 子句。
如果您事先不知道过滤值,例如如果您有多家公司,您可以为每家公司建立一个专门的索引。所以你最终会得到一些静态索引,如 FullTextIndexForXXXX、FullTextIndexForYYYY 等。
然后,此索引包含过滤,您可以使用 RavenDB Client api 提供的 GetTerms 函数来获取术语。
我必须动态构建索引定义。
我正在使用 IndexFactory 创建索引。
(必须在应用程序启动时调用)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Raven.Abstractions.Indexing;
using Raven.Client;
namespace MyNamespace.Data.Index.FullTextIndex
{
public static class FullTextIndexFactory
{
public static void CreateFullTextIndexes(IDocumentStore documentStore)
{
try
{
var companies = GetCompanies(documentStore);
foreach (var company in companies)
{
var indexName = "FullTextIndexFor" + company.Name;
var indexDefinition = CreateIndexDefinition(documentStore, company);
var existingIndexDefinition = documentStore.DatabaseCommands.GetIndex(indexName);
if (existingIndexDefinition == null)
{
CreateIndex(documentStore, indexDefinition, indexName);
continue;
}
if (existingIndexDefinition.Equals(indexDefinition))
continue;
UpdateIndex(documentStore, indexDefinition, indexName);
}
}
catch (Exception exception)
{
// do something with the exception
}
}
public static void CreateIndex(IDocumentStore documentStore, IndexDefinition indexDefinition, string indexName)
{
documentStore.DatabaseCommands.PutIndex(indexName, indexDefinition);
}
public static void UpdateIndex(IDocumentStore documentStore, IndexDefinition indexDefinition, string indexName)
{
documentStore.DatabaseCommands.DeleteIndex(indexName);
CreateIndex(documentStore, indexDefinition, indexName);
}
public static IndexDefinition CreateIndexDefinition(IDocumentStore documentStore, Company company)
{
var indexDefinition = new IndexDefinition();
var mapBuilder = new StringBuilder();
mapBuilder.AppendLine("docs.Topics.SelectMany(topic => topic.Content, (topic, content) => new");
mapBuilder.AppendLine("{");
mapBuilder.AppendLine(" topic = topic,");
mapBuilder.AppendLine(" content = content");
mapBuilder.AppendLine("})");
mapBuilder.AppendFormat(".Where(this0 => this0.topic.CompanyName == \"{0}\")", company.Name);
mapBuilder.AppendLine(".Select(this0 => new ");
mapBuilder.AppendLine("{");
mapBuilder.AppendLine(" CompanyName = this0.topic.CompanyName,");
mapBuilder.AppendLine(" Query = new object[]");
mapBuilder.AppendLine(" {");
mapBuilder.AppendLine(" this0.content.Value.Title,");
mapBuilder.AppendLine(" this0.content.Value.Description,");
mapBuilder.AppendLine(" this0.content.Value.Article");
mapBuilder.AppendLine(" },");
mapBuilder.AppendLine(" PublishStartDate = this0.topic.PublishStartDate,");
mapBuilder.AppendLine(" PublishEndDate = this0.topic.PublishEndDate,");
mapBuilder.AppendLine("})");
var map = mapBuilder.ToString();
indexDefinition.Maps.Add(map);
indexDefinition.Name = "FullTextIndexFor" + company.Name;
var analyzerAssemblyQualifiedName = typeof(CustomFullTextAnalyzer).AssemblyQualifiedName;
indexDefinition.Analyzers.Add("Query", analyzerAssemblyQualifiedName);
indexDefinition.Stores.Add("Query", FieldStorage.Yes);
return indexDefinition;
}
private static IEnumerable<Company> GetCompanies(IDocumentStore documentStore)
{
using (var session = documentStore.OpenSession())
{
return session.Query<Company>().ToList();
}
}
}
}
希望如果有人有类似要求,这会有所帮助。