【问题标题】:Issue with solrnet, manual mappings and required fieldssolrnet、手动映射和必填字段的问题
【发布时间】:2013-11-28 16:19:07
【问题描述】:

我被 solrnet 中的手动映射困住了,搜索 2 小时后我无法解释这种行为。 我使用手动映射来构建我的架构,并且一切正常,此外,当我尝试验证我的映射时,我不断收到错误。 当我运行查询时,目标对象的属性全部为 null 或为空。

我尝试这样做是因为我需要在 solrnet 前面开发一个通用层,该层应该用于我的一些不同的应用程序,因此我们希望避免在业务对象中使用元标记。

错误是指可能缺少的必填字段,但实际上我将它们映射为其他字段。 映射错误:

Required field 'doc_id' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'.
Required field 'author' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'.

以此类推,5 个必填字段,5 个错误。

在下文中,我提供了用于映射类型的架构和设置。 如果有人知道出了什么问题,我将不胜感激...... 提前谢谢你,

马库斯

schema字段,schema已经在solr服务器上运行,3000个测试文档也加载成功:

 <field name="_root_" type="string" indexed="true" stored="false"/>
<field name="doc_id"                   type="string"  indexed="true" stored="true" required="true" multiValued="false" />
<field name="author"                  type="string"   indexed="true" stored="true" required="true" />
<field name="author_gid"               type="string"   indexed="true" stored="true" required="true" />
<field name="applies_to"               type="string"   indexed="true" stored="false" required="false" />   
<field name="creation_date"            type="date"     indexed="true" stored="true" required="true" />
<field name="archive_date"             type="date"     indexed="true" stored="true" required="false" />
<field name="doc_acl"                   type="int"      indexed="true" stored="true" required="false" />
<field name="doc_status"                type="string"   indexed="true" stored="true" required="false" />






我的架构的基类。 (Doc 代表我的 Document 类)

public abstract class Schema
{
    protected Schema()
    {
        this.Fields              = new List<Field>();
        this.fieldDictionary     = new Dictionary<PropertyInfo, Field>();
        this.fieldNameDictionary = new Dictionary<PropertyInfo, string>();
    }

    public List<IMappingExpression> FieldMap;
    public List<Field> Fields { get; set; }
    public Field KeyField { get; set; }

    private readonly Dictionary<PropertyInfo, Field> fieldDictionary;
    private readonly Dictionary<PropertyInfo, string> fieldNameDictionary; 

    public abstract void BuildMap();


    public Schema Add(PropertyInfo property, string fieldName)
    {
        var field = new Field(fieldName, property);
        this.Fields.Add(field);
        this.fieldDictionary.Add(property,field);
        this.fieldNameDictionary.Add(property,fieldName);
        return this;
    }

    public PropertyInfo GetPropertyFor(string propertyName)
    {
        PropertyInfo property = null;
        List<Field> findAll = this.Fields.FindAll(match => match.Property.Name == propertyName);
        if (findAll.Count>1)
        {
            throw new Exception("property names have to be unique!");
        }
        if (findAll.Count==1)
        {
            property = findAll[0].Property;
        }
        return property;
    }

    public Field GetFieldFor(PropertyInfo property)
    {
        Field returnValue = null;

        if (!this.fieldDictionary.TryGetValue(property,out returnValue))
        {
            throw new IndexOutOfRangeException("unknown property!");
        }
        return returnValue;
    }

    public string GetFieldNameFor(PropertyInfo property)
    {
        string returnValue = null;

        if (!this.fieldNameDictionary.TryGetValue(property, out returnValue))
        {
            throw new IndexOutOfRangeException("unknown property!");
        }
        return returnValue;
    }

    //TODO: add default search field for default query behaviour


}



public class DocSchema : Schema
{
    public DocSchema()
    {
        this.BuildMap();
    }

    public override void BuildMap()
    {
        var keyProperty = GetPropertyInfo("DocId");

        this.KeyField = new Field("doc_id",keyProperty);
        //this.Add(keyProperty, "doc_id");

        this.Add(GetPropertyInfo("Author"), "author");
        this.Add(GetPropertyInfo("AppliesTo"), "applies_to");
        this.Add(GetPropertyInfo("AuthorGid"), "author_gid");
        this.Add(GetPropertyInfo("CreationDate"), "creation_date");
        this.Add(GetPropertyInfo("ArchiveDate"), "archive_date");
        this.Add(GetPropertyInfo("Description"), "description");
        this.Add(GetPropertyInfo("DocAcl"), "doc_acl");
        this.Add(GetPropertyInfo("DocStatus"), "doc_status");
        this.Add(GetPropertyInfo("DocLinks"), "doc_links");
        this.Add(GetPropertyInfo("DocType"), "doc_type");
        this.Add(GetPropertyInfo("Hits"), "hits");
        this.Add(GetPropertyInfo("InternalInformation"), "internal_information");
        this.Add(GetPropertyInfo("Modality"), "modality");
        this.Add(GetPropertyInfo("InternalInformationAcl"), "internal_information_acl");
        this.Add(GetPropertyInfo("ModifyDate"), "modify_date");
        this.Add(GetPropertyInfo("ProductName"), "product_name");
        this.Add(GetPropertyInfo("PublishDate"), "publish_date");
        this.Add(GetPropertyInfo("Publisher"), "publisher");
        this.Add(GetPropertyInfo("PublisherGid"), "publisher_gid");
        this.Add(GetPropertyInfo("PublishStatus"), "publish_status");
        this.Add(GetPropertyInfo("Rating"), "parent_doc_id");
        this.Add(GetPropertyInfo("ParentDocId"), "rating");
        this.Add(GetPropertyInfo("Resolution"), "resolution");
        this.Add(GetPropertyInfo("Title"), "title");
        this.Add(GetPropertyInfo("ReviewDate"), "review_date");
        this.Add(GetPropertyInfo("Products"), "products");
        this.Add(GetPropertyInfo("ImageNames"), "image_names");
        this.Add(GetPropertyInfo("AttachmentNames"), "attachment_names");
        this.Add(GetPropertyInfo("Attachments"), "attachments");
        this.Add(GetPropertyInfo("Text"), "text");
        this.Add(GetPropertyInfo("TextRev"), "text_rev");
        this.Add(GetPropertyInfo("Images"), "images");

    }

    private PropertyInfo GetPropertyInfo(string fieldName)
    {
        var property = typeof(Doc).GetProperty(fieldName);
        return property;
    }
}

它会像这样在 solrnet 中映射:

 public class SolrSchemaRegistrator : ISchemaRegistrator
{
    public void Register(Schema schema)
    {
        MappingService.Instance.MappingManager.Add(schema.KeyField.Property, schema.KeyField.FieldName);
        MappingService.Instance.MappingManager.SetUniqueKey(schema.KeyField.Property);

        foreach (Field field in schema.Fields)
        {
            MappingService.Instance.MappingManager.Add(field.Property, field.FieldName);
        }

        var container = new Container(Startup.Container);
        container.RemoveAll<IReadOnlyMappingManager>();
        container.Register<IReadOnlyMappingManager>(c => MappingService.Instance.MappingManager);
    }
}

但是当我像这样检查映射时:

 Startup.Init<Doc>("http://localhost:8983/solr");
        ISolrOperations<Doc> solr = ServiceLocator.Current.GetInstance<ISolrOperations<Doc>>();

        IList<ValidationResult> mismatches = solr.EnumerateValidationResults().ToList();
        var errors = mismatches.OfType<ValidationError>();
        var warnings = mismatches.OfType<ValidationWarning>();
        foreach (var error in errors)
            Debug.WriteLine("Mapping error: " + error.Message);
        foreach (var warning in warnings)
            Debug.WriteLine("Mapping warning: " + warning.Message);
        if (errors.Any())
            throw new Exception("Mapping errors, aborting");

我得到以下输出:

Mapping error: Required field 'doc_id' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'.
Mapping error: Required field 'author' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'.
Mapping error: Required field 'author_gid' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'.
Mapping error: Required field 'creation_date' in the Solr schema is not mapped in type 'Wise.ClientService.SkbDoc'

我真的不明白... 我有没有提到 solrnet 的 MappingManager 在调试器中看起来不错,具有正确的字段数?

【问题讨论】:

标签: solr solrnet


【解决方案1】:

Mauricio Scheffer 实际上为我解决了这个问题, 容器注册缺少一行。

此处的链接显示了解决方案: https://github.com/mausch/SolrNet/issues/117

这里是完整的代码

  var mapper = new MappingManager();
  /* Here come your mappings */
  var container = new Container(Startup.Container);
  container.RemoveAll<IReadOnlyMappingManager>();
  container.Register<IReadOnlyMappingManager>(c => mapper);
  ServiceLocator.SetLocatorProvider(() => container);
  Startup.Init<Document>("http://localhost:8983/solr");

【讨论】:

    猜你喜欢
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    相关资源
    最近更新 更多