MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Персонализирани функции изчислени колони mongodb проекция

Изглежда смятате, че е възможно да извикате функция на JavaScript в конвейера за агрегиране, но не можете да направите това. Грешите какво всъщност е "интерполация" на променлива от резултат от функция за изпълнение в рамките на конвейера.

Например, ако направя това:

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

Тогава наричам това:

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

Тогава какво всъщност се случва в обвивката на JavaScript, стойностите се „интерполират“ и „преди“ инструкцията да бъде изпратена на сървъра, както следва:

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

За по-нататъшна демонстрация на това, запазете функция "само" на сървъра:

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

След това опитайте да изпълните оператора за агрегиране:

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

И това ще доведе до изключение:

E QUERY [main] ReferenceError:hello не е дефиниран в (shell):1:69

Което е така, защото изпълнението се случва на „клиента“, а не на „сървъра“ и функцията не съществува на клиента.

Рамката за агрегиране не може стартирайте JavaScript, тъй като няма разпоредба за това. Всички операции се извършват в собствен код, без да се извиква JavaScript машина. Затова вместо това използвате операторите там:

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

Ако не можете да използвате операторите, за да постигнете резултатите, тогава единственият начин да стартирате JavaScript код е вместо това да стартирате mapReduce, който разбира се използва JavaScript двигател за взаимодействие с данните от колекцията. И от там можете също да препратите функция от страна на сървъра във вашата логика, ако трябва:

{ "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 } }
)

Връща:

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

Така че тук не става дума за „как да се предаде стойност на поле“, а всъщност за факта, че рамката за агрегиране не поддържа JavaScript по никакъв начин и че това, което си мислехте, че се случва, всъщност не е така.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да обедините документи при импортиране на файл в MongoDB

  2. MongoDB $nin оператор за заявка

  3. Мангуста:дълбока популация (населете населено поле)

  4. Как мога да съхранявам времето от деня в MongoDB? Като низ? Дайте произволна година/месец/ден?

  5. Защо производителността на Mongodb е по-добра на Linux, отколкото на Windows?