簡體   English   中英

C# mongodb驅動查詢嵌套數組

[英]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();

也許只有一件小事需要改變,它就會奏效。 我希望有人可以幫助我解決這個問題。

MongoDb 游樂場

謝謝

像這樣的東西應該可以工作,你需要做一個匹配,展開,匹配然后替換根

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM