We kunnen de $type
niet gebruiken
operator om onze documenten hier te filteren omdat het type elementen in onze array "string" is en zoals vermeld in de documentatie:
Maar gelukkig biedt MongoDB ook de $exists
operator die hier kan worden gebruikt met een numerieke matrixindex.
Hoe kunnen we die documenten nu bijwerken?
Welnu, vanaf MongoDB-versie <=3.2 is de enige optie die we hebben mapReduce()
maar laten we eerst eens kijken naar het andere alternatief in de aanstaande release van MongoDB.
Vanaf MongoDB 3.4 kunnen we $project
onze documenten en gebruik de $split
operator om onze string te splitsen in een array van substrings.
Merk op dat om alleen die "tags" die een string zijn te splitsen, we een logische nodig hebben $cond
ition-verwerking om alleen de waarden te splitsen die string zijn. De voorwaarde hier is $eq
die evalueren tot true
wanneer de $type
van het veld is gelijk aan "string"
. Trouwens $type
hier is nieuw in 3.4.
Eindelijk kunnen we de oude collectie overschrijven met behulp van de $out
exploitant van pijpleidingen. Maar we moeten de opname van een ander veld expliciet specificeren in het $project
podium .
db.collection.aggregate(
[
{ "$project": {
"tags": {
"$cond": [
{ "$eq": [
{ "$type": "$tags" },
"string"
]},
{ "$split": [ "$tags", " " ] },
"$tags"
]
}
}},
{ "$out": "collection" }
]
)
Met mapReduce
, moeten we de Array.prototype.split()
om de reeks substrings uit te zenden in onze kaartfunctie . We moeten onze documenten ook filteren met de optie "query". Van daaruit moeten we de array "results" herhalen en $set
de nieuwe waarde voor "tags" die bulkbewerkingen gebruiken met behulp van de bulkWrite()
methode nieuw in 3.2 of de nu verouderde Bulk()
als we op 2.6 of 3.0 zitten zoals hier
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']