c# MongoDB Filter返回整个对象



我试图在c#中创建一个MongoDB过滤器。例如,我有一个JSON对象,像这样:

"Username": "Tinwen",
"Foods": [
{
"Fruit": "Apple",
"Amount": 1
},
{
"Fruit": "Banana",
"Amount": 2
},
{
"Fruit": "Mango",
"Amount": 3
},
{
"Fruit": "Strawberry",
"Amount": 3
}
]
}

我想创建一个过滤器,只返回数组中的对象与Amount == 2 || Amount == 3:

{
"Username": "Tinwen",
"Foods": [
{
"Fruit": "Banana",
"Amount": 2
},
{
"Fruit": "Mango",
"Amount": 3
},
{
"Fruit": "Strawberry",
"Amount": 3
}
]
}

我已经尝试过这样的过滤器:

var amountFilter= Builders<MyObject>.Filter.ElemMatch(
m => m.Foods,
f => f.Amount == 2 || f.Amount == 3);

还有这个

var expected = new List<int>();
expected.Add(2);
expected.Add(3);
var amountFilter = Builders<MyObject>.Filter.And(Builders<MyObject>.Filter.ElemMatch(
x => x.Foods, Builders<Foods>.Filter.And(
Builders<Foods>.Filter.In(y => y.Amount, expected))));

但是每次它都会返回整个对象(包含完整数组)。现在我像这样使用LinQ:

List<MyObject> res = _messageCollection.Find(amountFilter).ToEnumerable().ToList();
foreach (var msg in res)
{
for (int j = 0; j < msg.Foods.Count; j++)
{
if (!expected.Contains(msg.Foods[j].Amount))
{
msg.Foods.RemoveAt(j);
}
}
}
for (int i = 0; i < res.Count; i++)
{
if (res[i].Foods.Count == 0)
{
res.RemoveAt(i);
}
}

但我很确定它可以使用MongoDB过滤器(也因为它是相当糟糕的与LinQ)。所以如果有人有答案可以帮助我!

您可以使用linq执行如下操作。但你必须让Foods属性为IEnumerable<Food>

public class User
{
public string Username { get; set; }
public IEnumerable<Food> Foods { get; set; }
}

下面的查询将在Foods数组/列表上执行$filter投影。

var result = await collection
.AsQueryable()
.Where(x => x.Foods.Any(f => f.Amount == 2 || f.Amount == 3))
.Select(x => new User
{
Username = x.Username,
Foods = x.Foods.Where(f => f.Amount == 2 || f.Amount == 3)
})
.ToListAsync();

最新更新