我在查询Mongo-DB集合时遇到了困难。
我正在使用的文件
{
CustomerId: 2,
Addresses: [
{
Name: "Daniel"
},
{
Name: "Eric"
},
{
Name: "Dan"
}
]
}
一些样本数据
var mdb = mongoClient.GetDatabase("test");
var collection = mdb.GetCollection<WebApi>("Customer");
var builder = Builders<Customer>.Filter;
var searchTerm = "Dan";
我现在想要通过CustomerId查询文档并过滤一些Addresses-values以返回名称为%Dan%的所有地址。由于地址集合可能很大,我想在查询时过滤这些地址
var filter = builder.And(builder.Eq("InstallationId", 2),
builder.Regex("Addresses.Name", new BsonRegularExpression(".*" + searchTerm + ".*", "i")))
var result = collection.Find(filter).FirstOrDefault();
当查询时,它可以工作,但它包含所有地址:
[
{
Name: "Daniel"
},
{
Name: "Dan"
}
]
我想得到的是:
{
CustomerId: 2,
Addresses: [
{
Name: "Daniel"
},
{
Name: "Dan"
}
]
}
或
collection.AsQueryable().Where(x => x.CustomId == 2).SelectMany(x =>
x.Addresses.Where(a => a.Name.IndexOf(searchTerm, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();
我还尝试了几种使用Aggregate / Match / Project的方法但无法使其工作。 “AsQueryable”也不起作用,因为没有在驱动程序上实现IndexOf。
select
fromdate,
employeename,
noofleaves,
substring(employeename,1,charindex(',',employeename)-2) as empname,
substring(employeename,(charindex(',',employeename))+1,(len(employeename)-(charindex(',',employeename)))) as leavetype
from tablename
已使用的版本:
答案 0 :(得分:2)
这应该让你前进:
var result = collection
.Aggregate()
.Match(c => c.CustomerId == 2)
.Project(c => new
{
c.CustomerId,
Addresses = c.Addresses.Where(a => a.Name.IndexOf(searchTerm) != -1)
})
.ToList();
驱动程序会将其转换为:
db.Customer.aggregate([{
$match: { CustomerId: 2 }
}, {
$project: {
CustomerId: "$CustomerId",
Addresses: {
$filter: {
input: "$Addresses",
as: "a",
cond: {
$ne: [ { $indexOfBytes: [ "$$a.Name", "Dan" ] }, -1 ]
}
}
},
_id: 0
}
}])
对于不区分大小写的版本,将来可以选择在某个阶段使用$ regex(请参阅https://jira.mongodb.org/browse/SERVER-11947)。但是,您现在可以使用ToUpper()
:
var result = collection
.Aggregate()
.Match(c => c.CustomerId == 2)
.Project(c => new
{
c.CustomerId,
Addresses = c.Addresses.Where(a => a.Name.ToUpper().IndexOf(searchTerm.ToUpper()) != -1)
})
.ToList();