MongoDB non fornire un modo per fare questo, fuori dalla scatola, ma avete ancora due opzioni:
Il primo è un'elaborazione lato client che utilizza il metodo Array.prototype.sort
per ordinare il risultato dell'array.
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);
})
Il secondo che è quello che vi consiglio di fare è normalizzare i documenti con un campo aggiuntivo che contengono i le cifre nel campo "Nome" come intero e ordinare i documenti utilizzando quel valore. Ciò significa che sarà necessario aggiornare i documenti per aggiungere quel campo e il modo migliore per farlo è utilizzare l'operatore di aggiornamento $set
e "bulk operations" per la massima efficienza. Detto questo, dal server MongoDB versione 3.2 è necessario utilizzare il metodo collection.bulkWrite
per ottenere ciò.
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);
Da server di MongoDB versione 2.6 è necessario utilizzare l'ormai deprecato 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();
Da versione server MongoDB 2.4 in poi è necessario un approccio diverso.
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 } }
);
})
Dopo qualsiasi di questa operazione, i documenti ora simile a questa:
{ "_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 }
Ora, si può facilmente risolvere i documenti utilizzando il metodo .sort
.
db.mydata.find({}, { "name": 1 }).sort({ "fileId": 1 })
che produce il seguente risultato:
{ "_id" : ObjectId("571e5a787e88d30b20b7857c"), "name" : "file1" }
{ "_id" : ObjectId("571e5a977e88d30b20b7857f"), "name" : "file2" }
{ "_id" : ObjectId("571e5a8c7e88d30b20b7857d"), "name" : "file11" }
{ "_id" : ObjectId("571e5a937e88d30b20b7857e"), "name" : "file22" }
fa tutti loro hanno 'file' comune in loro ?? – kryshna
No, @kryshna, questo è un insieme di dati semplificato. – 6220119
Non sono sicuro di come 'file1