Ответ 1
MongoDB не предоставляет способ сделать это из коробки, но у вас все еще есть две возможности:
Первая - обработка на стороне клиента с использованием метода Array.prototype.sort
для сортировки результата массива.
db.mydata.find().toArray().sort((a, b) => {
var x = Number(a.name.match(/\d+/g)[0]);
var y = Number(b.name.match(/\d+/g)[0]);
return x === y ? 0 :( x < y ? -1 : 1 );
})
Во-вторых, это то, что я предлагаю вам сделать, это нормализовать ваши документы с дополнительным полем, в котором цифры "имя" будут целочисленными и отсортировать ваши документы с использованием этого значения. Это означает, что вам нужно будет обновить свои документы, чтобы добавить это поле, и лучший способ сделать это - использовать оператор обновления $set
и "массовые операции" для максимальной эффективности. При этом с сервера MongoDB версии 3.2 вам необходимо использовать метод collection.bulkWrite
.
var requests = [];
db.mydata.find({}, { "name": 1 } ).forEach(doc => {
var fileId = Number(doc.name.match(/\d+/g)[0]); // return number from "name" value
requests.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "fileId": fileId } }
}
});
// Execute per 1000 operations and re-init the requests queue
if( requests.length === 1000 )
db.mydata.bulkWrite(requests);
})
// Clean up queues
if (requests.length > 0)
db.mydata.bulkWrite(requests);
От сервера MongoDB версии 2.6 вам нужно использовать теперь устаревший Bulk
API.
var bulk = db.mydata.initializeUnorderedBulkOp();
var count = 0;
db.collection.find({}, { "name": 1 }).forEach(function(doc) {
var fileId = Number(doc.name.match(/\d+/g)[0]);
bulk.find({"_id": doc._id}).updateOne({
"$set": { "fileId": fileId }
});
count++;
if (count % 1000 === 0) {
bulk.execute();
bulk = db.mydata.initializeUnorderedBulkOp();
}
})
if (count > 0)
bulk.execute();
От сервера MongoDB версии 2.4 и далее вам нужен другой подход.
db.collection.find({}, { "name": 1 }).forEach(function(doc) {
var fileId = Number(doc.name.match(/\d+/g)[0]);
db.collection.update(
{ "_id": doc._id },
{"$set": { "fileId": fileId } }
);
})
После любой из этих операций ваши документы теперь выглядят следующим образом:
{ "_id" : ObjectId("571e5a787e88d30b20b7857c"), "name" : "file1", "fileId" : 1 }
{ "_id" : ObjectId("571e5a8c7e88d30b20b7857d"), "name" : "file11", "fileId" : 11 }
{ "_id" : ObjectId("571e5a977e88d30b20b7857f"), "name" : "file2", "fileId" : 2 }
{ "_id" : ObjectId("571e5a937e88d30b20b7857e"), "name" : "file22", "fileId" : 22 }
Теперь вы можете легко отсортировать свои документы с помощью метода .sort
.
db.mydata.find({}, { "name": 1 } ).sort( { "fileId": 1 } )
который дает следующий результат:
{ "_id" : ObjectId("571e5a787e88d30b20b7857c"), "name" : "file1" }
{ "_id" : ObjectId("571e5a977e88d30b20b7857f"), "name" : "file2" }
{ "_id" : ObjectId("571e5a8c7e88d30b20b7857d"), "name" : "file11" }
{ "_id" : ObjectId("571e5a937e88d30b20b7857e"), "name" : "file22" }