[英]C# mongodb driver query nested array
幾個小時以來,我一直在努力讓一個查詢正常工作。 我的 shema 如下所示:
public class ActionResponse
{
public string Id { get; set; }
public List<ActionResponseItem> ResponseItems { get; set; }
}
public class ActionResponseItem
{
public string Id { get; set; }
public DateTime Created { get; set; }
public List<string> Options { get; set; }
}
假設我有以下收藏:
[
{
"_id": ObjectId("62bd901c4af4e9d2e1287984"),
"ResponseItems": [
{
"_id": ObjectId("62bd9068b4598dd0bb07b536"),
"Created": ISODate("2022-05-30T08:45:31.662Z"),
"Options": [
"Some string 1",
"Some string 2"
]
},
{
"_id": ObjectId("62bd906e35087e146b6b28f6"),
"Created": ISODate("2022-05-30T08:46:56.192Z"),
"Options": [
"Some string 3",
"Some string 4"
]
}
]
},
{
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": [
{
"_id": ObjectId("62bd62ab886b3fde8368ec39"),
"Created": ISODate("2022-06-30T08:45:31.662Z"),
"Options": [
"Some string 1",
"Some string 2"
]
},
{
"_id": ObjectId("62bd6300886b3fde8368ec3f"),
"Created": ISODate("2022-06-30T08:46:56.192Z"),
"Options": [
"Some string 3",
"Some string 4"
]
},
{
"_id": ObjectId("62bd6349886b3fde8368ec46"),
"Created": ISODate("2022-06-30T08:48:09.226Z"),
"Options": null
},
{
"_id": ObjectId("62bd64a88f5b6b24b6de199e"),
"Created": ISODate("2022-06-30T08:54:00.450Z"),
"Options": null
},
{
"_id": ObjectId("62bd64aa8f5b6b24b6de19a7"),
"Created": ISODate("2022-06-30T08:54:02.767Z"),
"Options": null
},
{
"_id": ObjectId("62bd64af8f5b6b24b6de19b1"),
"Created": ISODate("2022-06-30T08:54:07.896Z"),
"Options": null
},
{
"_id": ObjectId("62bd64b38f5b6b24b6de19bc"),
"Created": ISODate("2022-06-30T08:54:11.837Z"),
"Options": null
},
{
"_id": ObjectId("62bd64b78f5b6b24b6de19c8"),
"Created": ISODate("2022-06-30T08:54:15.588Z"),
"Options": [
"Some string 5",
"Some string 6"
]
},
{
"_id": ObjectId("62bd64bd8f5b6b24b6de19d5"),
"Created": ISODate("2022-06-30T08:54:21.494Z"),
"Options": [
"Some string 7"
]
},
{
"_id": ObjectId("62bd654d8f5b6b24b6de331d"),
"Created": ISODate("2022-06-30T08:56:45.487Z"),
"Options": null
}
]
}
]
我想獲得幾個條件匹配的列表,例如: ActionResponse.Id = '5e29560a2c4c55d421a4e1b4' & ActionResponseItem.Created >= ISODate("2022-06-30T08:54:17Z") & ActionResponseItem.Created <= ISODate("2022 -06-30T10:09:18.403Z")並僅返回嵌套元素,例如:
[
{
"_id": ObjectId("62bd64b78f5b6b24b6de19c8"),
"Created": ISODate("2022-06-30T08:54:15.588Z"),
"Options": [
"Some string 5",
"Some string 6"
]
},
{
"_id": ObjectId("62bd64bd8f5b6b24b6de19d5"),
"Created": ISODate("2022-06-30T08:54:21.494Z"),
"Options": [
"Some string 7"
]
},
{
"_id": ObjectId("62bd654d8f5b6b24b6de331d"),
"Created": ISODate("2022-06-30T08:56:45.487Z"),
"Options": null
}
]
我已經嘗試了幾個查詢(有/沒有聚合、投影)等等......
使用此查詢僅返回第一個匹配元素:
Mongo
db.collection.find({
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:13:21.754Z")
}
}
}
},
{
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:13:21.754Z")
}
}
}
})
C#
var filter = Builders<ActionResponse>.Filter.Eq(a => a.Id, id);
var nestedFilter = Builders<ActionResponseItem>.Filter.Gte(x => x.Created, from) &
Builders<ActionResponseItem>.Filter.Lte(x => x.Created, to);
var elements = await _collection
.Find(filter & Builders<ActionResponse>.Filter.ElemMatch(b => b.ResponseItems, nestedFilter))
.Project(Builders<ActionResponse>.Projection
.ElemMatch(c => c.ResponseItems, nestedFilter))
.ToListAsync();
這樣就返回了整個文檔:
Mongo
db.collection.aggregate([
{
"$match": {
"_id": ObjectId("5e29560a2c4c55d421a4e1b4"),
"ResponseItems": {
"$elemMatch": {
"Created": {
"$gte": ISODate("2022-06-30T08:54:17Z"),
"$lte": ISODate("2022-06-30T10:09:18.403Z")
}
}
}
}
}
])
C#
var filter = Builders<ActionResponse>.Filter.Eq(a => a.Id, id);
var nestedFilter = Builders<ActionResponseItem>.Filter.Gte(x => x.Created, from) &
Builders<ActionResponseItem>.Filter.Lte(x => x.Created, to);
var elements = await _collection.Aggregate()
.Match(filter & Builders<ActionResponse>.Filter.ElemMatch(b => b.ResponseItems, nestedFilter))
.ToListAsync();
也許只有一件小事需要改變,它就會奏效。 我希望有人可以幫助我解決這個問題。
謝謝
像這樣的東西應該可以工作,你需要做一個匹配,展開,匹配然后替換根
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
var client = new MongoClient();
var itemFilter =
Builders<UnwindResponseItemsActionResponse>.Filter.Gte(x => x.ResponseItems.Created,
new DateTime(2022, 06, 30, 08, 54, 17, DateTimeKind.Utc))
& Builders<UnwindResponseItemsActionResponse>.Filter.Lte(x => x.ResponseItems.Created,
new DateTime(2022, 06, 30, 10, 09, 18, 403, DateTimeKind.Utc));
var actionResponseItems = await client.GetDatabase("test")
.GetCollection<ActionResponse>("actions")
.Aggregate()
.Match(Builders<ActionResponse>.Filter.Eq(x => x.Id, "5e29560a2c4c55d421a4e1b4"))
.Unwind<ActionResponse, UnwindResponseItemsActionResponse>(x => x.ResponseItems)
.Match(itemFilter)
.ReplaceRoot(x => x.ResponseItems)
.ToListAsync();
foreach (var item in actionResponseItems)
{
Console.WriteLine(item.Id);
Console.WriteLine(item.Created);
Console.WriteLine();
}
/*
*
62bd64bd8f5b6b24b6de19d5
30/06/2022 08:54:21
62bd654d8f5b6b24b6de331d
30/06/2022 08:56:45
*/
public class UnwindResponseItemsActionResponse
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public ActionResponseItem ResponseItems { get; set; }
}
public class ActionResponse
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public List<ActionResponseItem> ResponseItems { get; set; }
}
public class ActionResponseItem
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public DateTime Created { get; set; }
public List<string> Options { get; set; }
}```
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.