Сохранить подмножество коллекции MongoDB в другой коллекции - PullRequest
53 голосов
/ 15 марта 2012

У меня есть такой набор

{date: 20120101}
{date: 20120103}
{date: 20120104}
{date: 20120005}
{date: 20120105}

Как сохранить подмножество этих документов с датой «20120105» в другой коллекции?

т.е. db.subset.save(db.full_set.find({date: "20120105"}));

Ответы [ 6 ]

80 голосов
/ 11 августа 2014

В качестве более нового решения я бы посоветовал использовать структуру агрегации для задачи:

db.full_set.aggregate([ { $match: { date: "20120105" } }, { $out: "subset" } ]);

Он работает примерно в 100 раз быстрее, чем forEach, по крайней мере, в моем случае. Это связано с тем, что весь конвейер агрегации выполняется в процессе mongod, а решение, основанное на find() и insert(), должно отправить все документы с сервера на клиент, а затем обратно. Это снижает производительность, даже если сервер и клиент находятся на одном компьютере.

58 голосов
/ 15 марта 2012

Вот версия оболочки:

db.full_set.find({date:"20120105"}).forEach(function(doc){
   db.subset.insert(doc);
});

Примечание: Начиная с MongoDB 2.6, структура агрегации позволяет делать это быстрее;подробности см. в ответе Мелана.

17 голосов
/ 19 декабря 2013

На самом деле, в MongoDB есть эквивалент insert into ... select from SQL.Сначала вы конвертируете несколько документов в массив документов;затем вы вставляете массив в целевую коллекцию

db.subset.insert(db.full_set.find({date:"20120105"}).toArray())
15 голосов
/ 29 сентября 2014

Самое общее решение таково:

Воспользуйтесь агрегацией (ответ дан @melan):

db.full_set.aggregate({$match:{your query here...}},{$out:"sample"})
db.sample.copyTo("subset")

Это работает, даже если до операции есть документы в «подмножестве», и вы хотите сохранить эти «старые» документы и просто вставить в них новое подмножество.

Необходимо соблюдать осторожность, поскольку команда copyTo() заменяет документы тем же _id.

3 голосов
/ 15 марта 2012

Нет прямого эквивалента SQL insert into ... select from ....

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

Вы можете сделать это в оболочке, но я бы использовал небольшой внешний скрипт в Ruby. Как то так:

require 'mongo'

db = Mongo::Connection.new.db('mydb')

source = db.collection('source_collection')
target = db.collection('target_collection')

source.find(date: "20120105").each do |doc|
  target.insert doc
end
1 голос
/ 15 августа 2018

Mongodb имеет агрегат и оператор $ out, которые позволяют сохранять подмножество в новой коллекции. Ниже приведены подробности:

$ out Берет документы, возвращенные конвейером агрегации, и записывает их в указанную коллекцию.

  • Операция $ out создает новую коллекцию в текущей базе данных, если она еще не существует.
  • Коллекция не видна до завершения агрегации.
  • В случае сбоя агрегации MongoDB не создает коллекцию.

Синтаксис:

{ $out: "<output-collection>" }

Пример Сборник книг содержит следующие документы:

{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }

Следующая операция агрегирования поворачивает данные в коллекции книг, чтобы заголовки были сгруппированы по авторам, а затем записывает результаты в коллекцию авторов.

db.books.aggregate( [
  { $group : { _id : "$author", books: { $push: "$title" } } },
    { $out : "authors" }
] )

После операции собрание авторов содержит следующие документы:

{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

В заданном вопросе используйте следующий запрос, и вы получите новую коллекцию с именем 'col_20120105' в вашей базе данных

 db.products.aggregate([
  { $match : { date : "20120105" } },
  { $out : "col_20120105" }
]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...