1

I'm trying query documents alongside with the list of attachments on RavenDB.

I have the following object:

 public class Post { public string Id { get; set; } public string Url { get; set; } public Profile Profile { get; set; } public DateTime CreatedOn { get; set; } [JsonProperty("@metadata")] public Metadata Metadata { get; set; } } public class Metadata { [JsonProperty("@attachments")] public List<AttachmentName> Attachments { get; set; } } 

When I try to execute the following query:

return await query.Select(x => new Repository.SummaryPost { Id = x.Id, CreatedOn = x.CreatedOn, Url = x.Url, AttachmentNames = x.Metadata.Attachments.Select(x => x.Name), Profile = new Repository.SummaryProfile { Id = x.Profile.Id, Name = x.Profile.Name, Url = x.Profile.Url, Source = new Repository.SummarySource { Id = x.Profile.Source.Id, Name = x.Profile.Source.Name, Url = x.Profile.Source.Url } } }).ToListAsync() 

It tries to run the following RQL:

from 'Posts' as x order by CreatedOn desc select { Id : id(x), CreatedOn : x.CreatedOn, Url : x.Url, AttachmentNames : x.@[email protected](function(x){return x.Name;}), Profile : { Id:x.Profile.Id, Name:x.Profile.Name, Url:x.Profile.Url, Source:{ Id:x.Profile.Source.Id, Name:x.Profile.Source.Name, Url:x.Profile.Source.Url } } } limit $p0, $p1 

Which is invalid and it throws the following error:

 ---> Esprima.ParserException: Line 5: Unexpected token ILLEGAL at Esprima.Scanner.ThrowUnexpectedToken(String message) at Esprima.Scanner.ScanPunctuator() at Esprima.JavaScriptParser.NextToken() at Esprima.JavaScriptParser.ParseLeftHandSideExpressionAllowCall() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseUpdateExpression() at Esprima.JavaScriptParser.ParseUnaryExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseExponentiationExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseBinaryExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseConditionalExpression() at Esprima.JavaScriptParser.ParseAssignmentExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseObjectProperty(Token hasProto) at Esprima.JavaScriptParser.ParseObjectInitializer() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParsePrimaryExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseLeftHandSideExpressionAllowCall() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseUpdateExpression() at Esprima.JavaScriptParser.ParseUnaryExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseExponentiationExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseBinaryExpression() at Esprima.JavaScriptParser.InheritCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseConditionalExpression() at Esprima.JavaScriptParser.ParseAssignmentExpression() at Esprima.JavaScriptParser.IsolateCoverGrammar[T](Func`1 parseFunction) at Esprima.JavaScriptParser.ParseExpression() at Esprima.JavaScriptParser.ParseReturnStatement() at Esprima.JavaScriptParser.ParseStatement() at Esprima.JavaScriptParser.ParseStatementListItem() at Esprima.JavaScriptParser.ParseScript(Boolean strict) at Raven.Server.Documents.Queries.QueryMetadata.HandleSelectFunctionBody(BlittableJsonReaderObject parameters) in C:\Builds\RavenDB-Stable-5.1\51018\src\Raven.Server\Documents\Queries\QueryMetadata.cs:line 601 

This is due to x.@metadata.@attachments if I run the same query without the metadata on Raven Studio, it runs without problems.

I'd like to know if I'm missing something, or if there is a proper way to achieve that.

1 Answer 1

1

After some try and error attempts I could figure it out how to properly do it.

First, there is no need to use those JsonProperty notation. Second, to properly query the metadata we need to use getMetadata(x) from RQL, and to generate that query we need to modify that LINQ to use RavenQuery.Metadata(x). Something like this:

 return await query.Select(x => new Repository.SummaryPost { Id = x.Id, CreatedOn = x.CreatedOn, Url = x.Url, Metadata = RavenQuery.Metadata(x)["@attachments"], Profile = new Repository.SummaryProfile { Id = x.Profile.Id, Name = x.Profile.Name, Url = x.Profile.Url, Source = new Repository.SummarySource { Id = x.Profile.Source.Id, Name = x.Profile.Source.Name, Url = x.Profile.Source.Url } } }).ToListAsync(); 

That that will generate the following RQL:

from 'Posts' as x order by CreatedOn desc select { Id : id(x), CreatedOn : x.CreatedOn, Url : x.Url, Metadata : getMetadata(x)["@attachments"], Profile : { Id:x.Profile.Id, Name:x.Profile.Name, Url:x.Profile.Url, Source:{ Id:x.Profile.Source.Id, Name:x.Profile.Source.Name, Url:x.Profile.Source.Url } } } limit $p0, $p1 

Fetching the list of documents alongside with the list of attachments.

Further we can even be more specific and query only the attachment names, by adding the following line to LINQ query:

AttachmentNames = ((IEnumerable<AttachmentName>) RavenQuery.Metadata(x)["@attachments"]).Select(x => x.Name) 

It will generate the following RQL for the AttachmentNames field:

AttachmentNames : getMetadata(x)["@attachments"].map(function(x){return x.Name;}) 

Querying only the names.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.