Как я могу отфильтровать Mongodb специфицируя c вложенный документ - PullRequest
0 голосов
/ 02 апреля 2020

Считайте, что у вас есть Order и OrderDetails. Я пытаюсь отфильтровать детали заказа для указанного c заказа. Например, если у вас есть что-то вроде этого:

{
  "orders": [
    {
      "id": 1,
      "date": "02.04.2020 ...",
      "user": {
        "name": "xx",
        "surname": "yy"
      },
      "orderDetails": [
        {
          "id": 1,
          "productId": 5,
          "quantity": 1,
          "state": 3
        },
        {
          "id": 2,
          "productId": 3,
          "quantity": 4,
          "state": 3
        },
        {
          "id": 3,
          "productId": 4,
          "quantity": 12,
          "state": 2
        },
        {
          "id": 4,
          "productId": 7,
          "quantity": 8,
          "state": 2
        },
        {
          "id": 5,
          "productId": 12,
          "quantity": 9,
          "state": 3
        }
      ]
    },
    {
      "id": 2,
      "date": "01.04.2020 ...",
      "user": {
        "name": "xx",
        "surname": "yy"
      },
      "orderDetails": [
        {
          "id": 6,
          "productId": 5,
          "quantity": 1,
          "state": 3
        },
        {
          "id": 7,
          "productId": 3,
          "quantity": 4,
          "state": 3
        },
        {
          "id": 8,
          "productId": 4,
          "quantity": 12,
          "state": 2
        }
      ]
    }
}

Я пытаюсь сначала выполнить фильтрацию по заказу, а затем состояние детализации заказа. У меня есть такой код, но он всегда приносит правильный порядок со всеми orderDetails. Похоже, ему не важен равный фильтр для orderDetails.
На самом деле он работает, но не фильтрует. Потому что у меня есть только 3 типа состояния (enum), а значения int равны 1,2,3. Запрос ничего не приносит, если я дам 4.

var builder = Builders<Order>.Filter;
var filter = builderk.And(builder.Eq("_id", ObjectId.Parse(elementid)), builder.Eq("orderDetails.state", 3));
var result = _mongoRepository.FindByFilter(filter).ToList();

Я также пробовал AnyEq и что-то подобное, но фильтры не работали.
Я буду очень рад, если кто-нибудь сможет мне помочь.
Спасибо ,

1 Ответ

2 голосов
/ 07 апреля 2020

Вы можете использовать операцию агрегирования для таких операций, как сортировка фильтра в подробных записях.

Если мы продолжим изучение образца, сначала необходимо создать фильтр для основных данных.

var builderMaster = Builders<Order>.Filter;
var filterMaster = builderMaster.Eq("_id", ObjectId.Parse(elementid));

Затем вам нужно создать другой фильтр для деталей. Важно : Вы должны использовать тип BsonDocument при создании подробных фильтров. Поскольку вы не можете указать конкретный тип c при фильтрации подробностей.

var builderDetail = Builders<BsonDocument>.Filter;
var filterDetail = builderDetail.Eq("orderDetails.state", 3);

Тогда вы можете начать вводить запрос.

var list = _mongoRepository.Aggregate()
                            .Match(filterMaster)
                            .Unwind("orderDetails")// Name the details.
                            .Match(filterDetail)
                            .Sort(sort)// optionally
                            .Skip(skip) // optionally
                            .Limit(limit) // optionally
                            .ToList();

Это даст вам список BsonDocument с заданными параметрами. После этого вы должны отобразить свой собственный класс деталей.

var resultList = new List<OrderDetails>();
foreach (var master in list)
            {
                var masterObj = BsonSerializer.Deserialize<dynamic>(master);
                foreach (var item in masterObj)
                {
                    if (item.Key == "orderDetails")
                    {
                        var mapper = new MapperConfiguration(cfg => { }).CreateMapper();
                        var retItem = mapper.Map<OrderDetails>(item.Value);

                        resultList.Add(retItem);
                    }
                }
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...