Как я могу вычесть массив в MongoDB - PullRequest
0 голосов
/ 25 июня 2018

Данные в MongoDB выглядят так:

{ "_id" : ObjectId("5b30d15d1e8b07d6a659ea81"), "group" : "2", "data" : { "count" : [  {  "f1" : 56,  "f2" : 48 },  {  "f1" : 95,  "f2" : 6 } ] } }
{ "_id" : ObjectId("5b30d1671e8b07d6a659ea82"), "group" : "3", "data" : { "count" : [  {  "f1" : 15,  "f2" : 72 },  {  "f1" : 56,  "f2" : 74 } ] } }
{ "_id" : ObjectId("5b30d1731e8b07d6a659ea83"), "group" : "4", "data" : { "count" : [  {  "f1" : 12,  "f2" : 96 },  {  "f1" : 85,  "f2" : 85 } ] } }
{ "_id" : ObjectId("5b30d17c1e8b07d6a659ea84"), "group" : "5", "data" : { "count" : [  {  "f1" : 73,  "f2" : 56 },  {  "f1" : 96,  "f2" : 79 } ] } }

Мне нужно получить данные, где f1 - f2 > 0, что означает, что мне нужны первая и четвертая записи и отфильтровать вторую и третью записи.Как я могу это сделать?

Есть ли что-то похожее на db.events.find({"$and":[{"difference":{"$subtract":{"data.count.f1": "data.count.f2"}}}, {"difference": {"$gt": 0}}]})?

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Используя оператор $expr (встречается в версиях 3.6 и выше) в качестве выражения запроса метода find(), вы можете использовать $anyElementTrue оператор, который принимает массив как набор и возвращает true, если любой из элементов имеет значение true, и false в противном случае. Пустой массив возвращает false.

Чтобы создать массив с элементами, которые оцениваются в true или false на основе логики вычитания выше, используйте $map, чтобы выполнить итерацию по массиву счетчиков и вернуть оцененную логику.

Следующее показывает это в действии:

db.getCollection('collection').find(
    {
        "$expr": {
            "$anyElementTrue": [
                { "$map": {
                    "input": "$data.count",
                    "as": "count",
                    "in": { 
                        "$gt": [
                            { "$subtract": [ "$$count.f1", "$$count.f2" ] },
                            0
                        ]
                    }
                } }
            ]
        }
    }
)

Для более ранних версий вы можете использовать $redact следующим образом:

db.getCollection('collection').aggregate([
    {
        "$redact": {
            "$cond": [
                {
                    "$anyElementTrue": [
                        { "$map": {
                            "input": "$data.count",
                            "as": "count",
                            "in": { 
                                "$gt": [
                                    { "$subtract": [ "$$count.f1", "$$count.f2" ] },
                                    0
                                ]
                            }
                        } }
                    ]
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])
0 голосов
/ 25 июня 2018

вам нужно использовать агрегацию для этого, потому что $subtract можно использовать только на стадии $project. Вот запрос агрегации:

db.collection.aggregate([
  {
    "$unwind": "$data.count"
  },
  {
    "$project": {
      "group": 1,
      "data": 1,
      "diff": {
        "$subtract": [
          "$data.count.f1",
          "$data.count.f2"
        ]
      }
    }
  },
  {
    "$match": {
      "diff": {
        "$gt": 0
      }
    }
  }
])

, вы можете попробовать его здесь: mongoplayground.net / р / Jp_G6Q0y26Q

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