如何在SolrNet中对多个表执行索引/搜索
本文关键字:执行 索引 搜索 SolrNet | 更新日期: 2023-09-27 17:50:27
我正在使用SolrNet在一组表上索引/搜索数据。
我有两个表类别和项目。
两个表有相同的字段,因此我有一个基映射类的形式,我派生。
[Serializable]
[XmlRoot(ElementName = "SolrSearchEntity", Namespace = "")]
[DataContract(Name = "SolrSearchEntity", Namespace = "")]
public class SolrSearchEntity
{
[XmlElement(ElementName = "Id")]
[DataMember(Name = "Id", IsRequired = true)]
[SolrUniqueKey("id")]
public string Id { get; set; }
[XmlElement(ElementName = "Name")]
[DataMember(Name = "Name", IsRequired = true)]
[SolrField("name")]
public string Name { get; set; }
}
public class Category : SolrSearchEntity
{
}
public class Item : SolrSearchEntity
{
}
索引目录数据的代码块
using (SolrBaseRepository.Instance<Category> repository = new SolrBaseRepository.Instance<Category>())
{
var output = ItemStoreDataManager.GetAllCategoryNames(dataAdapter);
repository.Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<Category>>();
solr.AddRange(output);
solr.Commit();
}
索引项目数据的代码块
using (SolrBaseRepository.Instance<Item> repository = new SolrBaseRepository.Instance<Item>())
{
var output = ItemStoreDataManager.GetAllItemNames(dataAdapter);
repository.Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<Item>>();
solr.AddRange(output);
solr.Commit();
}
My Schema.xml有
<fields>
<!-- declare fields of entity class -->
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="name" type="text_general" indexed="true" stored="true" omitNorms="true"/>
<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
</fields>
查询目录
中的数据 var entities = ItemStoreManager<Category>.Search(keyword); which will internally execute this.
new SolrBaseRepository.Instance<T>().Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
var results = solr.Query(keyword);
奇怪的是,我正在从项表中获取记录。
我如何告诉SolrNet(搜索引擎)查找我指定的类型
或者我一开始就正确地索引?
请帮助。
谢谢,
当您将数据添加到索引并基于客户端上的已知类型进行查询时,您将数据分开,您将其存储在Solr中的相同模式中,并且没有指定任何方法来区分Solr中的项目和类别记录。我建议您修改您的模式,以包含一个类型字段,该字段可以只是一个简单的字符串,例如:
<field name="type" type="string" indexed="true" stored="true" />
然后您需要将类型字段添加到SolrSearchEntity基类中,并在Category和Item类中适当地设置它。如下所示:
[Serializable]
[XmlRoot(ElementName = "SolrSearchEntity", Namespace = "")]
[DataContract(Name = "SolrSearchEntity", Namespace = "")]
public class SolrSearchEntity
{
[XmlElement(ElementName = "Id")]
[DataMember(Name = "Id", IsRequired = true)]
[SolrUniqueKey("id")]
public string Id { get; set; }
[XmlElement(ElementName = "Name")]
[DataMember(Name = "Name", IsRequired = true)]
[SolrField("name")]
public string Name { get; set; }
[SolrField("type")]
public string Type {get; set;}
}
public class Category : SolrSearchEntity
{
public Category()
{
Type = "Category";
}
}
public class Item : SolrSearchEntity
{
public Item()
{
Type = "Item";
}
}
然后当你运行一个搜索,如果你想限制你的查询特定的类型,你可以添加一个过滤器查询像这样只搜索项目:
var entities = ItemStoreManager<Category>.Search(keyword);
new SolrBaseRepository.Instance<T>().Start();
var solr = ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
var options = new QueryOptions{
FilterQueries = new ISolrQuery[] { new SolrQueryByField("type","Item")}};
var results = solr.Query(keyword, options);
另外,要注意id值在数据库中不要重叠,否则将导致您只存储一个实体的一个实例(要么是类别,要么是项目,最后一个被索引的)。
最后,我认为你们目前的索引策略是合理的,不建议使用DIH。在我看来,使用SolrNet客户端库可以获得更多的控制和灵活性。我过去在使用数据导入处理程序时遇到过问题,发现使用SolrNet更容易管理和维护。
对于从DB索引多个表,我宁愿选择Solr DIH,因为它的灵活性,而不是任何客户端库。
除了库克提到的建议,
在SolrSearchEntity中添加GUID字段
[XmlElement(ElementName = "UId")]
[DataMember(Name = "UId", IsRequired = true)]
[SolrUniqueKey("uid")]
public Guid UId { get; set; }
初始化构造函数中的Uid
public Item()
{
Type = "Item";
UId = Guid.NewGuid();
}
schema.xml的修改
<fieldType name="uuid" class="solr.UUIDField" indexed="true" />
<!-- unique field -->
<field name="uid" type="uuid" indexed="true" stored="true" />
<uniqueKey>uid</uniqueKey>
现在索引将不会重叠或不一致,搜索将缩小到指定的类型