Nie możemy użyć $type
operator do filtrowania naszych dokumentów tutaj, ponieważ typ elementów w naszej tablicy to "string" i jak wspomniano w dokumentacji:
Ale na szczęście MongoDB udostępnia również $exists
operator, który może być użyty tutaj z indeksem tablicy numerycznej.
Jak możemy zaktualizować te dokumenty?
Cóż, od wersji MongoDB <=3.2, jedyną dostępną opcją jest mapReduce()
ale najpierw spójrzmy na inną alternatywę w nadchodzącym wydaniu MongoDB.
Począwszy od MongoDB 3.4, możemy $project
nasze dokumenty i użyj $split
operator, aby podzielić nasz ciąg na tablicę podciągów.
Zauważ, że aby podzielić tylko te „tagi”, które są ciągami, potrzebujemy logicznego $cond
przetwarzania, aby podzielić tylko wartości, które są ciągami. Warunek tutaj to $eq
które oceniają jako true
kiedy $type
pola jest równe "string"
. Przy okazji $type
oto nowość w 3.4.
Wreszcie możemy nadpisać starą kolekcję za pomocą $out
operator etapu rurociągu. Ale musimy wyraźnie określić włączenie innego pola do $project
scena .
db.collection.aggregate(
[
{ "$project": {
"tags": {
"$cond": [
{ "$eq": [
{ "$type": "$tags" },
"string"
]},
{ "$split": [ "$tags", " " ] },
"$tags"
]
}
}},
{ "$out": "collection" }
]
)
Z mapReduce
, musimy użyć Array.prototype.split()
emitować tablicę podciągów w naszej funkcji map . Musimy również filtrować nasze dokumenty za pomocą opcji "zapytanie". Stamtąd będziemy musieli iterować tablicę "results" i $set
nowa wartość dla „tagów” przy użyciu operacji zbiorczych przy użyciu bulkWrite()
nowa metoda w 3.2 lub przestarzała Bulk()
jeśli korzystamy z wersji 2.6 lub 3.0, jak pokazano tutaj.
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']