Сравните целые числа, хранящиеся как строки в Mongodb - PullRequest
1 голос
/ 03 февраля 2020

В приведенной ниже коллекции столбец "qty" содержит целочисленные значения, но тип данных является строкой.

Я хочу сравнить поле «кол-во» с целым числом в поле агрегата, а поле «склад» со строкой «А». ("qty"> 2 и "warehouse" = "A")

[Невозможно изменить тип данных в коллекции на целочисленный, поскольку имеется большая зависимость]

Редактировать : Необходимо получить все столбцы и все документы, соответствующие критериям.

Запрос : получение неверных результатов

db.runCommand(
    {
        aggregate: "products", pipeline: [
            {
                $match: {
                    instock: {
                        $elemMatch: {
                            warehouse: "A",
                            qty: { $gt: "2" }
                        }
                    }
                }
            },
            { $project: { _id: 0 } }],
        cursor: { batchSize: 200 }
    });

Результат : не получено документов, где элемент = журнал, хотя он удовлетворяет условиям

/* 1 */
{
    "item" : "paper",
    "instock" : [
        {
            "warehouse" : "A",
            "qty" : "60"
        },
        {
            "warehouse" : "B",
            "qty" : "15"
        }
    ]
},

/* 2 */
{
    "item" : "planner",
    "instock" : [
        {
            "warehouse" : "A",
            "qty" : "22"
        },
        {
            "warehouse" : "B",
            "qty" : "5"
        }
    ]
}

Коллекция продуктов

[
    {
        "item": "journal",
        "instock": [
            {
                "warehouse": "A",
                "qty": "11"
            },
            {
                "warehouse": "C",
                "qty": "15"
            }
        ]
    },
    {
        "item": "paper",
        "instock": [
            {
                "warehouse": "A",
                "qty": "60"
            },
            {
                "warehouse": "B",
                "qty": "15"
            }
        ]
    },
    {
        "item": "planner",
        "instock": [
            {
                "warehouse": "A",
                "qty": "22"
            },
            {
                "warehouse": "B",
                "qty": "5"
            }
        ]
    }
]

Получение неправильных результатов, поскольку оператор больше, чем в этом случае, работает лексикографически, но он должен работать как целые числа. Хотя я пытался преобразовать это в удвоение, но я не получил результатов.

Запрос с $ convert для удвоения : без результата

db.runCommand(
    {
        aggregate: "products", pipeline: [
            //{ $match: { "item": { $in: ["planner", "paper","journal"] } } },
            {
                $match: {
                    instock: {
                        $elemMatch: {
                            warehouse: "A",
                            qty: {
                                $gt: [
                                    {$convert:{ input: "$qty", to: "double" }}, 5]
                            }
                        }
                    }
                }
            },
            { $project: { _id: 0 } }],
        cursor: { batchSize: 200 }
    });

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Попробуйте это:

db.products.aggregate([
  {
    $unwind: "$instock"
  },
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              "$instock.warehouse",
              "A"
            ]
          },
          {
            $gt: [
              {
                $toInt: "$instock.qty"
              },
              2
            ]
          }
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      item: {
        $first: "$item"
      },
      instock: {
        $push: "$instock"
      }
    }
  },
  {
    $project: {
      _id: 0
    }
  }
])

MongoPlayground

0 голосов
/ 03 февраля 2020

Попробуйте, он использует $ фильтр для сохранения объектов имеет критерии:

db.runCommand(
    {
        aggregate: "products", pipeline: [
            { $match: { 'instock.warehouse': 'A' } },
            {
                $addFields: {
                    instockCheck: {
                        $filter: {
                            input: '$instock', as: 'each', cond: {
                                $and: [{ $gt: [{ $toInt: '$$each.qty' }, 2] },
                                { $eq: ['$$each.warehouse', 'A'] }]
                            }
                        }
                    }
                }
            }, { $match: { instockCheck: { $gt: [] } } }, { $project: { instockCheck: 0, _id: 0 } }],
        cursor: { batchSize: 200 }
   });

Тест: MongoDB-Playground

...