Vi kan inte använda $type
operatör för att filtrera våra dokument här eftersom typen av element i vår array är "sträng" och som nämnts i dokumentationen:
Men lyckligtvis tillhandahåller MongoDB också $exists
operator som kan användas här med ett numeriskt arrayindex.
Hur kan vi nu uppdatera dessa dokument?
Tja, från MongoDB version <=3.2 är det enda alternativet vi har mapReduce()
men låt först titta på det andra alternativet i den kommande versionen av MongoDB.
Från MongoDB 3.4 kan vi $project
våra dokument och använd $split
operatorn för att dela upp vår sträng i en array av delsträngar.
Observera att för att bara dela de "taggar" som är strängar behöver vi en logisk $cond
bearbetning för att bara dela upp värdena som är strängar. Villkoret här är $eq
som utvärderas till true
när $type
av fältet är lika med "sträng"
. Förresten $type
här är nytt i 3.4.
Slutligen kan vi skriva över den gamla samlingen med $out
rörledningsskedeoperatör. Men vi måste uttryckligen specificera inkluderingen av andra fält i $project
scen .
db.collection.aggregate(
[
{ "$project": {
"tags": {
"$cond": [
{ "$eq": [
{ "$type": "$tags" },
"string"
]},
{ "$split": [ "$tags", " " ] },
"$tags"
]
}
}},
{ "$out": "collection" }
]
)
Med mapReduce
, måste vi använda arrayen. prototype.split()
för att sända ut arrayen av delsträngar i vår kartfunktion . Vi måste också filtrera våra dokument med alternativet "fråga". Därifrån kommer vi att behöva iterera "results"-arrayen och $set
det nya värdet för "taggar" med bulkoperationer med Bulk()
om vi är på 2.6 eller 3.0 som visas här.
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']