使用RavenDB,可以获得索引的条款。此功能记录在here
简短的问题:在某种程度上可以通过索引的其他字段来过滤术语吗?
长问题: 我们正在创建一个知识库应用程序,客户可以在其中存储主题。
我们构建了一个用于全文搜索的索引,我们正在索引所有主题。在索引中,我们有2个可查询的属性:CompanyName,Query
public class SearchQueryResult
{
public string Query { get; set; }
public string CompanyName { get; set; }
}
public class FullTextIndex : AbstractIndexCreationTask<Topic, SearchQueryResult>
{
public FullTextIndex()
{
Map = topics => from topic in topics
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);
}
}
对于全文查询,我可以将结果限制为相应的用户公司。
var results = _documentSession.Query<SearchQueryResult, FullTextIndex>()
.Where(x => x.Query.StartsWith(input))
.Where(x => x.CompanyName == "MyCompany")
.OfType<Topic>()
.ToList();
我们想在搜索输入字段中添加一个AutoCompletion,为此我们需要获取索引的条款(查询字段)
问题是,索引确实包含所有公司的条款,我们只需要当前公司的条款。
在RavenDB Studio中,可以从索引中获取存储的,已分析的术语:
- &GT;如何在客户端代码中使用查询获取这些值?
感谢您的建议
答案 0 :(得分:0)
你可以查询这样的索引:
var results = _documentSession.Query<SearchQueryResult, FullTextIndex>()
.Where(x => x.CompanyName == "MyCompany")
.Select(x=>x.Query)
.ToList();
然后在结果上使用foreach循环,这将显示您的查询属性
Title, Description, Article
答案 1 :(得分:0)
没有其他方法可以获得索引的条款。要获得术语,客户端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();
}
}
}
}
希望如果有人有类似要求,这会有所帮助。