c# - C# MongoDB 2. 查找比较其字段的文档:不支持的过滤器
问题描述
我正在尝试以这种方式从 MongoDB 获取文档:
public async Task<IEnumerable<UnitModel>> GetUnits(string race)
{
var units = collection.Aggregate().Match(x => x.Race == race &&
(x.Attack < x.Def1 || x.Attack < x.Def2) &&
(x.UnitType == UnitType.Warrior || x.UnitType == UnitType.Archer));
return await units.ToListAsync();
}
但是会出现以下错误:
Unsupported filter: ({document}{attack} < {document}{def1}).
将 Where 与相同的谓词一起使用会导致相同的结果。我做错了什么?
更新:
据我了解,C# 驱动程序无法转换此查询。现在我正在尝试使用管道。首先,我在 shell 中测试了查询,它可以工作:
db.units.aggregate([
{
$addFields: {
cDiff: {$cmp: ['$attack','$def1']},
iDiff: {$cmp: ['$attack','$def2']}
}
},
{
$match: {
$and: [
{race: "elf"},
{$or: [
{
cDiff:{$eq:-1}
},
{
iDiff:{$eq:-1}
}
]},
{$or: [{
"unitType": "Warrior"
},
{
"unitType": "Archer"
}]}
]
}
}
]).pretty()
现在我坚持将其转换为 C#:
public async Task<IEnumerable<UnitModel>> GetDeffenceUnits(Race race)
{
PipelineDefinition<UnitModel, UnitModel> pipeline = new BsonDocument[]
{
new BsonDocument{
{ "$addFields", new BsonDocument
{
{ "iDiff:", new BsonDocument { { "$cmp", new BsonArray { "$attack", "$def1" } } } },
{ "cDiff:", new BsonDocument { { "$cmp", new BsonArray { "$attack", "$def2" } } } }
}
}
},
new BsonDocument
{
{
"$match", new BsonDocument
{
{
"$and", new BsonArray
{
new BsonDocument
{
{ "race", race.GetEnumDisplayName() }
},
new BsonDocument
{
{
"$or", new BsonArray
{
new BsonDocument
{
{ "iDiff", new BsonDocument { { "$eq", -1 } } }
},
new BsonDocument
{
{ "cDiff", new BsonDocument { { "$eq", -1 } } }
}
}
}
},
new BsonDocument
{
{
"$or", new BsonArray
{
new BsonDocument
{
{ "unitType", UnitType.Warrior.GetEnumDisplayName() }
},
new BsonDocument
{
{ "unitType", UnitType.Warrior.GetEnumDisplayName() }
}
}
}
}
}
}
}
}
}
};
var units = collection.Aggregate(pipeline);
return await units.ToListAsync();
}
此查询返回一个空列表。我错过了什么?
更新 2 添加 UnitModel:
[BsonIgnoreExtraElements]
public class UnitModel
{
public string Name { get; set; }
// enum
public Race Race { get; set; }
public double Expenses { get; set; }
public double Speed { get; set; }
public double Capacity { get; set; }
public double Attack { get; set; }
public double Def1 { get; set; }
public double Def2 { get; set; }
// enum
public UnitType UnitType { get; set; }
public ResourcesModel TrainingCost { get; set; }
public ResourcesModel ResearchCost { get; set; }
public TimeSpan ResearchTime { get; set; }
public TimeSpan TrainingTime { get; set; }
}
public class ResourcesModel
{
public int Wood { get; set; }
public int Gold { get; set; }
public int Iron { get; set; }
}
更新 3 试图查看 mongodb 请求:
var units = collection.Aggregate(pipeline);
var queryToMongo = units.ToString();
return await units.ToListAsync();
更新 4 约定包:
var packEnum = new ConventionPack
{
new EnumRepresentationConvention(BsonType.String)
};
ConventionRegistry.Register("EnumStringConvention", packEnum, t => true);
var packCamelCase = new ConventionPack
{
new CamelCaseElementNameConvention()
};
ConventionRegistry.Register("camel case",
packCamelCase,
t => t.FullName.StartsWith("TTB.DAL.Models"));
解决方案
你知道,这真的很尴尬......当我将我的 shell 查询复制到 C# 时,我忘记删除 iDiff 和 cDiff 之后的冒号。在我删除它们后,查询运行良好。
推荐阅读
- java - NFS(Netapp 服务器)-> Flink -> s3
- postgresql - 从 grafana 连接到 postgresql
- arrays - 如何在 Swift 中过滤对象以仅显示其值?
- javascript - 如何始终显示当前在 Canvas 对象上播放的音频对象的频率?
- java - 如何使用 Java 在 Selenium 中按键盘 ALT + I
- javascript - 在每个车轮事件上更改页面
- r - 在 R 中加载 csv 文件时出现无效的多字节字符串错误
- sql - 创建sql查询,将sybase数据库表中可用的数据批量生成csv文件
- c# - 无法在 xml 查询中将字符串转换为数字类型
- javascript - JavaScript 异步迭代器加入/减少