无法在 RavenDB 上查询附件
Can't query attachments on RavenDB
我正在尝试查询文档以及 RavenDB 上的附件列表。
我有以下对象:
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; }
}
当我尝试执行以下查询时:
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()
它尝试 运行 以下 RQL:
from 'Posts' as x
order by CreatedOn desc
select {
Id : id(x),
CreatedOn : x.CreatedOn,
Url : x.Url,
AttachmentNames : x.@metadata.@attachments.map(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
无效并抛出以下错误:
---> 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.1018\src\Raven.Server\Documents\Queries\QueryMetadata.cs:line 601
这是由于 x.@metadata.@attachments
如果我 运行 在 Raven Studio 上没有元数据的相同查询,它 运行 没有问题。
我想知道我是否遗漏了什么,或者是否有实现该目的的正确方法。
经过一些尝试和错误尝试后,我可以弄清楚如何正确地做到这一点。
首先,没有必要使用那些JsonProperty
符号。其次,要从 RQL 中正确查询我们需要使用 getMetadata(x)
的元数据,并且要生成该查询,我们需要修改 LINQ 以使用 RavenQuery.Metadata(x)
。像这样:
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();
那将生成以下 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
正在获取文档列表和附件列表。
此外,我们甚至可以更具体地查询附件名称,方法是将以下行添加到 LINQ 查询:
AttachmentNames = ((IEnumerable<AttachmentName>) RavenQuery.Metadata(x)["@attachments"]).Select(x => x.Name)
它将为 AttachmentNames
字段生成以下 RQL:
AttachmentNames : getMetadata(x)["@attachments"].map(function(x){return x.Name;})
仅查询名称。
我正在尝试查询文档以及 RavenDB 上的附件列表。
我有以下对象:
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; }
}
当我尝试执行以下查询时:
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()
它尝试 运行 以下 RQL:
from 'Posts' as x
order by CreatedOn desc
select {
Id : id(x),
CreatedOn : x.CreatedOn,
Url : x.Url,
AttachmentNames : x.@metadata.@attachments.map(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
无效并抛出以下错误:
---> 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.1018\src\Raven.Server\Documents\Queries\QueryMetadata.cs:line 601
这是由于 x.@metadata.@attachments
如果我 运行 在 Raven Studio 上没有元数据的相同查询,它 运行 没有问题。
我想知道我是否遗漏了什么,或者是否有实现该目的的正确方法。
经过一些尝试和错误尝试后,我可以弄清楚如何正确地做到这一点。
首先,没有必要使用那些JsonProperty
符号。其次,要从 RQL 中正确查询我们需要使用 getMetadata(x)
的元数据,并且要生成该查询,我们需要修改 LINQ 以使用 RavenQuery.Metadata(x)
。像这样:
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();
那将生成以下 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
正在获取文档列表和附件列表。
此外,我们甚至可以更具体地查询附件名称,方法是将以下行添加到 LINQ 查询:
AttachmentNames = ((IEnumerable<AttachmentName>) RavenQuery.Metadata(x)["@attachments"]).Select(x => x.Name)
它将为 AttachmentNames
字段生成以下 RQL:
AttachmentNames : getMetadata(x)["@attachments"].map(function(x){return x.Name;})
仅查询名称。