Czy łączysz się z tą samą przestrzenią nazw bazy danych w kodzie PHP, z którą łączyłeś się za pomocą powłoki? Myślę, że nie!
W każdym razie źle rozumiesz koncepcję $where
w tym kontekście, ponieważ możesz tylko oceniać a nie zwracać zmodyfikowane wyniki inne niż dane już zawarte w kolekcji.
Jedyne rzeczy, które faktycznie mogą zwrócić coś innego niż istniejące dokumenty, to .mapReduce()
i .aggregate()
.
Aby zademonstrować, w „tej samej przestrzeni nazw”, jeśli definiujesz kolekcję:
db.djunk.insert({ "x": 1, "y": 2 })
A następnie uruchom .mapReduce()
db.dbjunk.mapReduce(
function() {
emit(this._id, sum(this.x,this.y))
},
function() {}, // does nothing here where already unique
{ "out": { "inline": 1 } }
)
To by zwróciło rzeczywisty zsumowany wynik:
{
"_id" : ObjectId("571a9bb951d042a7a896fd92"),
"value" : 3
}
Całe to $where
może zrobić, to "logicznie" wybierz dokument:
db.djunk.find(function() {
return sum(this.x,this.y) > 3
})
Co nie spełnia warunku.
Ale oczywiście naprawdę nie musisz tego robić i generalnie powinieneś unikać wykonywania JavaScriptu przez serwer tam, gdzie to możliwe. Jest znacznie wolniejszy niż operatory natywne i możesz zrobić całkiem sporo z operatorami natywnymi.
Więc zamiast .mapReduce()
wywołaj .aggregate()
:
db.djunk.aggregate([
{ "$project": {
"total": { "$add": [ "$x", "$y" ] }
}}
])
I zamiast oceny JavaScript, wywołaj .aggregate()
ponownie, z $redact
dla filtrowania „logicznego”:
db.djunk.aggregate([
{ "$redact": {
"$cond": {
"if": { "$gt": [ { "$add": [ "$x", "$y" ] }, 3 ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Tak więc w większości przypadków zawsze istnieje lepsza alternatywa dla korzystania z ewaluacji JavaScript. I z pewnością istnieje bardzo niewiele przypadków, w których naprawdę potrzebne są funkcje przechowywane na serwerze w przypadkach, w których faktycznie wymagana jest ocena JavaScript.
Ale twoim podstawowym błędem będzie to, że funkcja znajdowała się w innej przestrzeni nazw lub, że w międzyczasie zrestartowałeś serwer. Ale ogólnie rzecz biorąc, prawdopodobnie i tak nie powinieneś używać przechowywanych funkcji.