【问题标题】:How to perform indexing/search on multiple tables in SolrNet如何在 SolrNet 中对多个表执行索引/搜索
【发布时间】:2013-01-02 07:49:26
【问题描述】:

我正在使用 SolrNet 来索引/搜索一组表中的数据。

我有两张表 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; }
    }

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();
                }

我的 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>

查询Category中的数据

  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);

奇怪的是,我正在从 Item 表中获取记录。

我将如何告诉 SolrNet(搜索引擎)在我指定的类型内查找。

或者我一开始就正确索引?

请帮忙。

谢谢,

【问题讨论】:

    标签: c# solr solrnet querying


    【解决方案1】:

    当您在将数据添加到索引并在客户端上基于已知类型进行查询时分离数据时,您将其全部存储在 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。 IMO,使用 SolrNet 客户端库,您将拥有更多的控制权和灵活性。过去我在使用数据导入处理程序时遇到过问题,发现使用 SolrNet 更容易管理和维护。

    【讨论】:

    • 谢谢库克。我已经采取了你建议的方法。但是,表的 id 值与运行数字相似(重叠)。因此,我得到不正确的数据,查询类别返回项目数据。如何处理?
    • 谢谢库克。我已经采取了你建议的方法。但是,表的 id 值与运行数字相似(重叠)。因此,我得到不正确的数据,查询类别返回项目数据。如何处理?
    【解决方案2】:

    为了从数据库中索引多个表,我宁愿选择Solr DIH,因为它的灵活性而不是任何客户端库。

    【讨论】:

      【解决方案3】:

      除了库克提到的建议,

      在 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>
      

      现在索引不会重叠或不一致,搜索将缩小到指定的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-25
        • 1970-01-01
        • 2017-06-10
        • 1970-01-01
        • 2021-02-14
        • 1970-01-01
        相关资源
        最近更新 更多