-1

I am stuck with manual mapping in solrnet and I cannot explain the behavior after searching for 2 hours. I use manual mapping to build up my schema, and everything works fine, besides that I keep getting errors when I try to validate my mapping. When I run queries the properties of the target objects are all null or empty.

I try to do this as I need to develop a generic layer in front of solrnet which should be used my some different applications, so we want to avoid using metatags in business objects.

The errors refer to required fields that would be missing, but actually I map them like the other fields. Mapping error:

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'.

And so on, 5 required fields, 5 errors.

In the following I provide my schema and teh setup I have for mapping the types. If anyone knows what's going wrong, I will highly appreciate... Thank you in advance,

Markus

The schema fields, the schema is already up and running on the solr server, 3000 test documents were also loaded successfully:

 <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" />






Base class for my schema. (Doc stands for my Document class)

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

And it gets mapped in solrnet like this:

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

But when I check the mapping like this:

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

I get the following output:

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'

And I really don't get it... Did I mention that the MappingManager of solrnet looks good in the debugger, having the correct number of fields?

Mitaksh Gupta
  • 1,029
  • 6
  • 24
  • 50

1 Answers1

0

Mauricio Scheffer actually solved it for me, there was a missing line for the container registration.

the link here shows the solution: https://github.com/mausch/SolrNet/issues/117

and here the full code

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