MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Funkcje niestandardowe obliczane kolumny mongodb projekcja

Wydaje Ci się, że możliwe jest wywołanie funkcji JavaScript w potoku agregacji, ale nie możesz tego zrobić. Mylisz to, co w rzeczywistości jest „interpolacją” zmiennej z wyniku funkcji do wykonania w potoku.

Na przykład, jeśli to zrobię:

var getNumbers = function() { return [ 1,2,3 ] };

Następnie nazywam to:

db.collection.aggregate([
    { "$project": {
        "mynums": getNumbers()
    }}  
])

Następnie, co faktycznie dzieje się w powłoce JavaScript, wartości są "interpolowane" i "przed" wysłaniem instrukcji na serwer, tak jak to:

db.collection.aggregate([
    { "$project": {
        "mynums": [1,2,3]
    }}  
])

Aby to dodatkowo zademonstrować, zapisz funkcję „tylko” na serwerze:

db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })

Następnie spróbuj uruchomić instrukcję agregacji:

db.collection.aggregate([
    { "$project": {
        "greeting": hello()
    }}  
])

A to spowoduje wyjątek:

E QUERY [główne] ReferenceError:cześć nie jest zdefiniowana w (powłoka)::1:69

Dzieje się tak, ponieważ wykonanie odbywa się na „kliencie”, a nie na „serwerze”, a funkcja nie istnieje na kliencie.

Struktura agregacji nie może uruchom JavaScript, ponieważ nie ma na to żadnego przepisu. Wszystkie operacje wykonywane są w kodzie natywnym, bez wywoływania silnika JavaScript. Dlatego zamiast tego używasz operatorów:

db.collection.aggregate([
    { "$project": {
        "total": { "$add": [ 1, 2 ] },
        "field_total": { "$subtract": [ "$gross", "$tax" ] }
    }}  
])   

Jeśli nie możesz użyć operatorów do osiągnięcia wyników, jedynym sposobem na uruchomienie kodu JavaScript jest uruchomienie zamiast tego mapReduce, które oczywiście wykorzystuje silnik JavaScript do łączenia się z danymi z kolekcji. Stamtąd możesz również odwołać się do funkcji po stronie serwera w swojej logice, jeśli potrzebujesz:

{ "key": 1, "value": 1 },
{ "key": 1, "value": 2 },
{ "key": 1, "value": 3 }

db.system.js.save({ "_id": "square", "value": function(num) { return num * num } })

db.collection.mapReduce(
    function() {
        emit(this.key,square(this.value))
    },
    function(key,values) {
        return Array.sum(values);
    },
    { "out": { "inline": 1 } }
)

Zwroty:

{
    "_id": 1,
    "value": 14
}

Nie chodzi więc o „jak przekazać wartość pola”, ale tak naprawdę o to, że struktura agregacji w żaden sposób nie obsługuje JavaScript i że to, co myślisz, że się dzieje, tak nie jest.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Dlaczego nie mogę debugować kodu w metodzie asynchronicznej?

  2. MongoDB .Net driver 2.0 Pull (usuń element)

  3. Pobieranie MongoDB w systemie Linux do nasłuchiwania połączeń zdalnych

  4. Odniesienia do dokumentów Mongoose z relacją jeden-do-wielu

  5. Kolejność dokumentów zwrotnych Mongodb find