.NET MongoDB 错误的投影规范
.NET MongoDB Bad Projection Specification
我正在将系统从旧 Mongo 驱动程序升级到新驱动程序。我遇到了以下查询的问题。
var orgsUnitReadModels = _readModelService.Queryable<OrganisationalUnitReadModel>()
.Where(x => locations.Contains(x.Id))
.Select(x => new AuditLocationItemViewModel
{
Id = x.Id,
Name = x.Name,
AuditRecordId = auditRecordId,
Type = type,
IsArchived = !x.IsVisible,
AuditStatus = auditStatus
}).ToList();
它产生以下错误消息,我不明白。如果您能协助解释这意味着什么以及如何解决它,我将不胜感激。
MongoDB.Driver.MongoCommandException: 'Command aggregate failed: Bad
projection specification, cannot exclude fields other than '_id' in an
inclusion projection: { Id: "$_id", Name: "$Name", AuditRecordId:
BinData(3, 5797FCCCA90C8644B4CB84FED4236D4B), Type: 0, IsArchived: {
$not: [ "$IsVisible" ] }, AuditStatus: 2, _id: 0 }.'
在此示例中,LINQ 的 Select 语句被翻译成 MongoDB 的 $project。通常,您使用 0
(或 false
)排除字段,并使用 1
或 true
将字段包含在最终结果集中。当然,您也可以使用美元语法来引用现有字段,例如 Name
.
问题是您还试图将一些 in-memory 常量值作为投影的一部分。不幸的是,其中一个 (type
) 等于 0
,这被解释为好像您想从管道结果中排除一个名为 Type
的字段。
由于这种歧义 MongoDB 引入了 $literal 运算符,您可以在 Mongo shell:
中尝试以下语法
db.col.aggregate([{ $project: { _id: 0, Id: 1, Name: 1, Type: { $literal: 0 } } }])
它将return 0
作为您期望的常量值。 MongoDB .NET 驱动程序文档提到了文字 here 但它看起来只适用于字符串。
有几种方法可以解决您的问题,我认为更简单的方法是先 运行 更简单的 .Select
语句,然后使用 .ToList()
确保查询已实现.完成后,您可以 运行 另一个 in-memory .Select()
来构建您的 OrganisationalUnitReadModel
:
.Where(x => locations.Contains(x.Id))
.Select(x => new { x.Id, x.Name, x.IsVisible }).ToList()
.Select(x => new AuditLocationItemViewModel
{
Id = x.Id,
Name = x.Name,
Type = type,
IsArchived = !x.IsVisible,
AuditStatus = auditStatus
}).ToList();
我正在将系统从旧 Mongo 驱动程序升级到新驱动程序。我遇到了以下查询的问题。
var orgsUnitReadModels = _readModelService.Queryable<OrganisationalUnitReadModel>()
.Where(x => locations.Contains(x.Id))
.Select(x => new AuditLocationItemViewModel
{
Id = x.Id,
Name = x.Name,
AuditRecordId = auditRecordId,
Type = type,
IsArchived = !x.IsVisible,
AuditStatus = auditStatus
}).ToList();
它产生以下错误消息,我不明白。如果您能协助解释这意味着什么以及如何解决它,我将不胜感激。
MongoDB.Driver.MongoCommandException: 'Command aggregate failed: Bad projection specification, cannot exclude fields other than '_id' in an inclusion projection: { Id: "$_id", Name: "$Name", AuditRecordId: BinData(3, 5797FCCCA90C8644B4CB84FED4236D4B), Type: 0, IsArchived: { $not: [ "$IsVisible" ] }, AuditStatus: 2, _id: 0 }.'
在此示例中,LINQ 的 Select 语句被翻译成 MongoDB 的 $project。通常,您使用 0
(或 false
)排除字段,并使用 1
或 true
将字段包含在最终结果集中。当然,您也可以使用美元语法来引用现有字段,例如 Name
.
问题是您还试图将一些 in-memory 常量值作为投影的一部分。不幸的是,其中一个 (type
) 等于 0
,这被解释为好像您想从管道结果中排除一个名为 Type
的字段。
由于这种歧义 MongoDB 引入了 $literal 运算符,您可以在 Mongo shell:
中尝试以下语法db.col.aggregate([{ $project: { _id: 0, Id: 1, Name: 1, Type: { $literal: 0 } } }])
它将return 0
作为您期望的常量值。 MongoDB .NET 驱动程序文档提到了文字 here 但它看起来只适用于字符串。
有几种方法可以解决您的问题,我认为更简单的方法是先 运行 更简单的 .Select
语句,然后使用 .ToList()
确保查询已实现.完成后,您可以 运行 另一个 in-memory .Select()
来构建您的 OrganisationalUnitReadModel
:
.Where(x => locations.Contains(x.Id))
.Select(x => new { x.Id, x.Name, x.IsVisible }).ToList()
.Select(x => new AuditLocationItemViewModel
{
Id = x.Id,
Name = x.Name,
Type = type,
IsArchived = !x.IsVisible,
AuditStatus = auditStatus
}).ToList();