Сопоставьте несколько значений в MongoDB с одним запросом в pymongo - PullRequest
1 голос
/ 28 мая 2020

У меня есть тест коллекции, который имеет следующие значения, из которых я должен получить документ на основе поля «значение», которое я могу легко получить из указанного ниже запроса.

db.getCollection('test').find({"value" : 100})

но настоящая проблема в том, что У меня есть список полей "значения", таких как [100,104,200152, .......], этот список может быть очень длинным, и я хочу, чтобы мой результат был в приведенном ниже формате, чтобы уменьшить количество запросов mon go как это занимает слишком много времени, если список, содержащий «значения», слишком велик, мне нужно выполнить несколько запросов mon go, чтобы получить все записи.

{100:[
    /* 1 */

    {
        "_id" : "C1",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 2 */
    {
        "_id" : "C2",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 3 */
    {
        "_id" : "C3",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 4 */
    {
        "_id" : "C4",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 5 */
    {
        "_id" : "CO",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 6 */
    {
        "_id" : "DD",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }

    /* 7 */
    {
        "_id" : "EX",
        "value" : 100,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }],

104:

    [{
        "_id" : "AU",
        "value" : 104,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }],
200152:

    [
    {
        "_id" : "GenFile",
        "value" : 200152,
        "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
        "timetaken" : 3.0
    }
    ]

DB

/* 1 */
{
    "_id" : "AU",
    "value" : 104,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 2 */
{
    "_id" : "C1",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 3 */
{
    "_id" : "C2",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 4 */
{
    "_id" : "C3",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 5 */
{
    "_id" : "C4",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 6 */
{
    "_id" : "CO",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 7 */
{
    "_id" : "DD",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 8 */
{
    "_id" : "EX",
    "value" : 100,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 9 */
{
    "_id" : "GS_SEG",
    "value" : 124755350,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

/* 10 */
{
    "_id" : "GenFile",
    "value" : 200152,
    "lastUpdatedTime" : ISODate("2019-11-04T00:00:00.000Z"),
    "timetaken" : 3.0
}

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Вы можете использовать следующую агрегацию, чтобы сделать работу за вас. Но у него будут поля значений 100, 104 в виде строк вместо чисел (мне пришлось использовать оператор toString, иначе я получал ошибку).

db.collection.aggregate([
  {
    $group: {
      _id: "$value",
      root: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $project: {
      k: {
        $toString: "$_id"
      },
      v: "$root",
      _id: 0
    }
  },
  {
    $group: {
      _id: null,
      x: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $project: {
      _id: 0,
      x: {
        $arrayToObject: "$x"
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: "$x"
    }
  }
])

Ниже будет вывод :

[
  {
    "1.24755e+08": [
      {
        "_id": "GS_SEG",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 1.2475535e+08
      }
    ],
    "100": [
      {
        "_id": "C1",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "C2",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "C3",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "C4",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "CO",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "DD",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      },
      {
        "_id": "EX",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 100
      }
    ],
    "104": [
      {
        "_id": "AU",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 104
      }
    ],
    "200152": [
      {
        "_id": "GenFile",
        "lastUpdatedTime": ISODate("2019-11-04T00:00:00Z"),
        "timetaken": 3,
        "value": 200152
      }
    ]
  }
]
1 голос
/ 28 мая 2020

Вы ищете в правильном направлении, вам нужно, чтобы ваш код не тратил большую часть времени на сетевые запросы. Оператор pymon go $in выбирает документы, в которых значение поля равно любому значению в указанном массиве.

В вашем случае это будет выглядеть так:

# Set or build a list of the values
list_with_values =  [100, 104, 200152]

# Make one call to the DB, asking for all of the matching records.
result = db.getCollection('test').find({"value" : {"$in": list_with_values})

Дополнительная информация о том, как работает оператор $in: http://docs.mongodb.org/manual/reference/operator/query/in/

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