Не можем да използваме $type
оператор за филтриране на нашите документи тук, защото типът на елементите в нашия масив е "низ" и както е споменато в документацията:
Но за щастие MongoDB предоставя и $exists
оператор, който може да се използва тук с числов индекс на масив.
Сега как можем да актуализираме тези документи?
Е, от MongoDB версия <=3.2, единствената опция, която имаме, е mapReduce()
но първо нека разгледаме другата алтернатива в предстоящото издание на MongoDB.
Започвайки от MongoDB 3.4, можем да $project
нашите документи и използвайте $split
оператор за разделяне на нашия низ на масив от поднизове.
Обърнете внимание, че за да разделим само тези „тагове“, които са низове, се нуждаем от логически $cond
ition обработка за разделяне само на стойностите, които са низ. Условието тук е $eq
които се оценяват като true
когато $type
от полето е равно на "string"
. Между другото $type
ето ново в 3.4.
Накрая можем да презапишем старата колекция с помощта на $out
оператор на тръбопроводен етап. Но трябва изрично да посочим включването на друго поле в $project
етапа .
db.collection.aggregate(
[
{ "$project": {
"tags": {
"$cond": [
{ "$eq": [
{ "$type": "$tags" },
"string"
]},
{ "$split": [ "$tags", " " ] },
"$tags"
]
}
}},
{ "$out": "collection" }
]
)
С mapReduce
, трябва да използваме Array.prototype.split()
за излъчване на масива от поднизове в нашата функция map . Също така трябва да филтрираме документите си с помощта на опцията "заявка". От там ще трябва да повторим масива „резултати“ и $set
новата стойност за "тагове", използващи групови операции с помощта на bulkWrite()
нов метод в 3.2 или вече отхвърления Bulk()
ако сме на 2.6 или 3.0, както е показано тук.
db.collection.mapReduce(
function() { emit(this._id, this.tags.split(" ")); },
function(key, value) {},
{
"out": { "inline": 1 },
"query": {
"tags.0": { "$exists": false },
"tags": { "$type": 2 }
}
}
)['results']