Indexes: Indexing Attachments
Syntax
Using AttachmentsFor()
The AttachmentsFor
method returns information about each attachment that extends
a specified document, including their names, sizes, and content type.
IEnumerable<AttachmentName> AttachmentsFor(object doc);
public string Name;
public string Hash;
public string ContentType;
public long Size;
The AttachmentsFor
method is available in AbstractIndexCreationTask
.
Using LoadAttachment()/LoadAttachments()
LoadAttachment()
loads an attachment to the index by document and attachment name.
LoadAttachments()
loads all the attachments of a given document.
public IAttachmentObject LoadAttachment(object doc, string name);
public IEnumerable<IAttachmentObject> LoadAttachments(object doc);
Parameter | Type | Description |
---|---|---|
doc | A server-side document, an entity | The document whose attachments you want to load |
name | string |
The name of the attachment you want to load |
GetContentAs Methods
To access the attachment content itself, use GetContentAsStream()
. To
convert the content into a string
, use GetContentAsString()
with
the desired character encoding.
public Stream GetContentAsStream();
public string GetContentAsString(Encoding encoding);
public string GetContentAsString(); // Default: UTF-8
Applications for Attachment Content: Machine Learning
Access to the attachment content opens the door to many different applications, including many that can be integrated directly into RavenDB.
In this blog post,
Oren Eini demonstrates how machine learning image recognition can be
added to an index using the additional sources
feature. The resulting index allows filtering and querying based on
image content.
Examples
Indexes with AttachmentsFor()
public class Employees_ByAttachmentNames : AbstractIndexCreationTask<Employee>
{
public class Result
{
public string[] AttachmentNames { get; set; }
}
public Employees_ByAttachmentNames()
{
Map = employees => from e in employees
let attachments = AttachmentsFor(e)
select new Result
{
AttachmentNames = attachments.Select(x => x.Name).ToArray()
};
}
}
public class Employees_ByAttachmentNames_JS : AbstractJavaScriptIndexCreationTask
{
public class Result
{
public string[] AttachmentNames { get; set; }
}
public Employees_ByAttachmentNames_JS()
{
Maps = new HashSet<string>
{
@"map('Employees', function (e) {
var attachments = attachmentsFor(e);
return {
AttachmentNames: attachments.map(
function(attachment) {
return attachment.Name;
}
};
})"
};
}
}
Indexes with LoadAttachment()
private class Companies_With_Attachments : AbstractIndexCreationTask<Company>
{
public Companies_With_Attachments()
{
Map = companies => from company in companies
let attachment = LoadAttachment(company, company.ExternalId)
select new
{
CompanyName = company.Name,
AttachmentName = attachment.Name,
AttachmentContentType = attachment.ContentType,
AttachmentHash = attachment.Hash,
AttachmentSize = attachment.Size,
AttachmentContent = attachment.GetContentAsString(Encoding.UTF8),
};
}
}
private class Companies_With_Attachments_JavaScript : AbstractJavaScriptIndexCreationTask
{
public Companies_With_Attachments_JavaScript()
{
Maps = new HashSet<string>
{
@"map('Companies', function (company) {
var attachment = loadAttachment(company, company.ExternalId);
return {
CompanyName: company.Name,
AttachmentName: attachment.Name,
AttachmentContentType: attachment.ContentType,
AttachmentHash: attachment.Hash,
AttachmentSize: attachment.Size,
AttachmentContent: attachment.getContentAsString('utf8')
};
})"
};
}
}
Indexes with LoadAttachments()
private class Companies_With_All_Attachments : AbstractIndexCreationTask<Company>
{
public Companies_With_All_Attachments()
{
Map = companies => from company in companies
let attachments = LoadAttachments(company)
from attachment in attachments
select new
{
AttachmentName = attachment.Name,
AttachmentContent = attachment.GetContentAsString(Encoding.UTF8)
};
}
}
private class Companies_With_All_Attachments_JS : AbstractJavaScriptIndexCreationTask
{
public Companies_With_All_Attachments_JS()
{
Maps = new HashSet<string>
{
@"map('Companies', function (company) {
var attachments = loadAttachments(company);
return attachments.map(attachment => ({
AttachmentName: attachment.Name,
AttachmentContent: attachment.getContentAsString('utf8')
}));
})"
};
}
}
Querying the Index
//return all employees that have an attachment called "cv.pdf"
List<Employee> employees = session
.Query<Employees_ByAttachmentNames.Result, Employees_ByAttachmentNames>()
.Where(x => x.AttachmentNames.Contains("cv.pdf"))
.OfType<Employee>()
.ToList();
//return all employees that have an attachment called "cv.pdf"
List<Employee> employees = await asyncSession
.Query<Employees_ByAttachmentNames.Result, Employees_ByAttachmentNames>()
.Where(x => x.AttachmentNames.Contains("cv.pdf"))
.OfType<Employee>()
.ToListAsync();
//return all employees that have an attachment called "cv.pdf"
List<Employee> employees = session
.Advanced
.DocumentQuery<Employee, Employees_ByAttachmentNames>()
.ContainsAny("AttachmentNames", new[] { "cv.pdf" })
.ToList();