Elasticsearch-net: NEST 1.0 - What is the new .MapFromAttributes()?

Created on 28 May 2014  路  18Comments  路  Source: elastic/elasticsearch-net

I have some POCOs that're decorated with attributes. Inside they look like this:

[Serializable]
[ElasticType(DisableAllField = true, IdProperty = ElasticsearchFields.FullUncPath)]
public class ShareDriveDocument
{
    [ElasticProperty(Name = ElasticsearchFields.Id, Type = FieldType.string_type, Store = true, Index = FieldIndexOption.not_analyzed)]
    public string Id { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.FullUncPath, Type = FieldType.string_type, Store = true, Index = FieldIndexOption.not_analyzed)]
    public string FullUncPath { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.FileName, Type = FieldType.string_type, Store = true, Index = FieldIndexOption.not_analyzed)]
    public string FileName { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.ParentDirectory, Type = FieldType.string_type, Store = true, Index = FieldIndexOption.not_analyzed)]
    public string ParentDirectory { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.DateCreated, Type = FieldType.date_type, Store = true, DateFormat = ElasticsearchDateFormats.NoMillis)]
    public DateTime DateCreated { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.DateModified, Type = FieldType.date_type, Store = true, DateFormat = ElasticsearchDateFormats.NoMillis)]
    public DateTime DateModified { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.SemanticFulltext, Type = FieldType.string_type, Store = true, IndexAnalyzer = "english")]
    public string SemanticFulltext { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.ExactFulltext, Type = FieldType.string_type, Store = true, IndexAnalyzer = "not_analyzed")]
    public string ExactFulltext { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.OriginalSize, Type = FieldType.long_type, Store = true)]
    public long OriginalFileSize { get; internal set; }

    [ElasticProperty(Name = ElasticsearchFields.TextSize, Type = FieldType.long_type, Store = true)]
    public long TextContentSize { get; internal set; }

    public ShareDriveDocument(IndexingJob indexingJob, string fulltext)
    {
        var fileInfo = new FileInfo(indexingJob.PathName);

        FullUncPath = indexingJob.PathName;
        FileName = Path.GetFileName(indexingJob.PathName);
        ParentDirectory = Path.GetDirectoryName(indexingJob.PathName);
        DateModified = fileInfo.LastWriteTimeUtc;
        DateCreated = fileInfo.CreationTimeUtc;
        SemanticFulltext = fulltext;
        ExactFulltext = fulltext;
        OriginalFileSize = fileInfo.Length;
        TextContentSize = fulltext.Length;
    }
    //...
}

Once upon a time, I could do this:

var client = new ElasticClient(connectionSettings);
//...
client.MapFromAttributes<ElasticsearchDocument>(TEST_INDEX, type);

But I can't anymore. client.Map<ShareDriveDocument>(m => m.MapFromAttributes()); triggers a runtime error. I suspect this is because m.MapFromAttributes() is a 0.12.* thing.

How do I accomplish this in 1.0?

Most helpful comment

@nasreekar I've opened #2085 to better handle attachments.

All 18 comments

Hi @rianjs

 client.Map<ShareDriveDocument>(m => m.MapFromAttributes());

Is indeed its replacement. Can you post the runtime exception you get?

A FileLoadException:

An unhandled exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll

Additional information: Could not load file or assembly 'Nest, Version=0.12.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Also, this page seems to be wrong:
http://nest.azurewebsites.net/nest/indices/put-mapping.html

var response = this.ConnectedClient.Map<ElasticSearchProject>();

.Map() doesn't take 0 parameters.

Hey @rianjs.

It tries to load NEST 0.12.0.0. Can you double check that all your references use 1.0.0 beta 1? Be sure to clean your bin folders as well.

I was referencing an old version of the nest library in one of my own libraries. Updating to the 1.0 version and rebuilding solved the FileNotFoundException.

great! Thanks for the followup :+1:

@rianjs Hi rianjs.. Im trying to use elastic property for my class variables and then use automap or map option for mapping the properties. But when i use elastic property, it is throwing an error saying

"The type of namespace Elasticproperty could not be found(are you missing a using directive or assembly reference")

image

can you please help me with this... TIA

@nasreekar Take a look at the NEST 2.x documentation, specifically the documentation on Automapping and on breaking changes between 1.x and 2.x.

@russcam Hi Russ, As per the documentation they say class AttachmentMapping is removed. In that case how can I re-write the below variable property? Can you please help me with this?

[String(Type = FieldType.Attachment, TermVector = TermVectorOption.WithPositionsOffsetsPayloads, Store = true, Index = FieldIndexOption.Analyzed)]
public Attachment File { get; set; }

@nasreekar You should use the fluent mapping in order to set an attachment type. The tests have an example of the mapping that should help.

There is an AttachmentAttribute but since all of its properties are _not_ primitive types, there is no way to set values for those properties in an attribute.

@russcam Thanks Russ. Does this work without using the AttachmentAttribute? Because Im trying to index the content of files in a folder(.pdf's,.docs etc).

 class Attachment
    {
        public string Id { get; set; }

        public string Name { get; set; }

        [String(TermVector = TermVectorOption.WithOffsets)]
        public string Content { get; set; }
    }

and indexing is done using the below code:

 settings = new ConnectionSettings(pool)
             .DefaultIndex(defaultIndex)
             .MapDefaultTypeNames(m => m.Add(typeof(Attachment), "docs"));

And then for reading the content

foreach (string file in Directory.GetFiles(path))
            {
                Attachment document = new Attachment
                {
                    Id = counter.ToString(),
                    Name = Path.GetFileNameWithoutExtension(file),
                    Content = Convert.ToBase64String(File.ReadAllBytes(file)),
                };
                counter++;
            }

I dont have any problem while indexing the documents and searching them with their Id's but the problem is with the content. It is displayed in ToBase64String Format and how can I search in the content of documents.

Attachment needs to be mapped as an attachment type using fluent mapping and the mapper-attachments plugin needs to be installed. The plugin uses Apache Tika to allow searching on document fields mapped with attachment type.

If Attachment is not mapped as attachment type then it will be mapped as an object type by NEST in which case you will _not_ be able to search across the document indexed as a Base64 string.

@russcam I installed the mapper attachments plugin. I think i am missing the "mapping it as an Attachment part."

@nasreekar what version of NEST are you using and what version of Elasticsearch are you running against?

@russcam
image

What version of Elasticsearch are you running against?

@russcam 2.3.1
image

@nasreekar I've opened #2085 to better handle attachments.

Was this page helpful?
0 / 5 - 0 ratings