Вычисляемые атрибуты (без кеширования)

Описание

Вычисляемые атрибуты (формулы) применяются для моментального формирования строкового выражения (результата) по заданному алгоритму при обращении к объекту класса через API. Например, при открытии объекта.

На уровне меты класса вычисляемые атрибуты хранят алгоритм формирования строкового выражения в свойстве formula.

Для примера можно получить все уникальные значения из атрибута name, значения которого хранятся в коллеции ownOrg. Затем уникальные значения с разделителями «,» между собой объединяются в одно строковое значение.

"formula": {
  "merge": [
    "$ownOrg",
    "name",
    null,
    1,
    ", "
  ]
}

Например, если есть коллекция с не уникальными значениями, например «ownOrg1», «ownOrg2». и снова «ownOrg1», то чтобы получить только уникальные значения коллекции «Организация 1 и Организация 2», пригодится выше описанная формула для вычисляемого атрибута с использованием функции merge.

В зависимости от функции можно обращаться к необходимому атрибуту для получения значения через атрибуты типа «Ссылка», «Коллекция».

При сохранении изменений и закрытии формы объекта результат не сохраняется в атрибуте, если не настроено кеширование.

Если в мете класса задано несколько вычисляемых атрибутов, то порядок их вычисления задается в свойстве orderNumber. При этом можно использовать результаты вычислений по заданному порядку orderNumber в последующих вычисляемых атрибутах.

В семантике класса или атрибута можно указывать вычисляемые атрибуты.

Если в свойстве formula задать Null, то атрибут не будет являться вычисляемым и кеширование к такому атрибуту не должно применяться.

Модель записи формулы

Каждая формула начинается с описания объекта и функции в формате JSON.

"formula": {
  "function1": [
    {
      "function2": [
        "operand3"
      ]
    },
    "operand1",
    "operand2"
  ]
}

В объекте обязательно нужно указать подходящую функцию необходимым количеством операндов для получения результата в function1.

В объекте содержится полное описание алгоритма, по которому будут происходить вычисления, за исключением тех функций, которые находятся в зависимых вычисляемых атрибутах.

Массив в функции хранит порядок операндов, которые передаются в функцию.

Операндами функции могут быть:

  • Строковые значения, хранящие константу

    "formula": {
      "function1": [
        "string"
      ]
    }
    
  • Строковые значения, хранящие переменные.

    "formula": {
      "function1": [
        "$attr1"
      ]
    }
    
  • Числовые значения

    "formula": {
      "function1": [
        3.14
      ]
    }
    
  • Пустые значения

    "formula": {
      "function1": [
        null
      ]
    }
    
  • Объекты

    "formula": {
      "function1": [
        {
          "function2": [
            "operand1"
          ]
        }
      ]
    }
    

Пример применения формулы:

{
      "orderNumber": 5,
      "name": "addressString",
      "caption": "",
      "type": 0,
      "size": null,
      "decimals": 0,
      "allowedFileTypes": null,
      "maxFileCount": 0,
      "nullable": true,
      "readonly": false,
      "indexed": true,
      "unique": false,
      "autoassigned": false,
      "hint": null,
      "defaultValue": null,
      "refClass": "",
      "itemsClass": "",
      "backRef": "",
      "backColl": "",
      "binding": "",
      "semantic": null,
      "selConditions": [],
      "selSorting": [],
      "selectionProvider": null,
      "indexSearch": false,
      "eagerLoading": false,
      "formula": {
        "concat": [
          {
            "if": [
              "$zipCode",
              {
                "concat": [
                  "$zipCode"
                ]
              },
              ""
            ]
          },
          " ",
          {
            "if": [
              "$subjectFederation",
              "$subjectFederation",
              ""
            ]
          },
          {
            "if": [
              "$federationBorough",
              {
                "concat": [
                  ", ",
                  "$federationBorough"
                ]
              },
              ""
            ]
          },
          {
            "if": [
              {
                "and": [
                  {
                    "ne": [
                      "$subjectFederation",
                      "Санкт-Петербург г"
                    ]
                  },
                  {
                    "ne": [
                      "$subjectFederation",
                      "Москва г"
                    ]
                  }
                ]
              },
              {
                "concat": [
                  ", ",
                  "$town"
                ]
              },
              ""
            ]
          },
          {
            "if": [
              "$street",
              {
                "concat": [
                  ", ",
                  "$street"
                ]
              },
              ""
            ]
          },
          {
            "if": [
              "$houseNumber",
              {
                "concat": [
                  ", Дом ",
                  "$houseNumber"
                ]
              },
              ""
            ]
          },
          {
            "if": [
              "$flatNumber",
              {
                "concat": [
                  ", Квартира (офис) ",
                  "$flatNumber"
                ]
              },
              ""
            ]
          }
        ]
      }
 }

Результат: вывод адреса с пробелами и запятыми между значениями атрибутов

Поддерживаемые функции

eq - равно

ne - не равно

lt - меньше

gt - больше

lte - меньше либо равно

gte - больше, либо равно

and - и

or - или

not - не

add - арифметическое сложение

sub - арифметическое вычитание

mul - арифметическое умножение

div - арифметическое деление

nempty - не пусто

empty - пусто

pad - дополнение строки символами до нужной длины

next - извлекает новое значение последовательности

merge - конкатенация атрибутов в коллекции

size - принимает в качестве аргумента атрибуты типа строка и коллекция. Для строк возвращает длину, для коллекций - количество элементов

element - получение произвольного элемента из массива, индексирование с 0 ([массив значений], [индекс элемента: 0 - первый элемент, last - последний элемент])

dateAdd - добавление к дате (в нотации momentjs - [Дата], [добавляемый интервал (число)], [ед.изм (строка [d, m, y, h, min, s, ms)])

dateDiff - разница между датами (в нотации momentjs - [ед.изм], [Дата1], [Дата2])

now - текущая дата-время

concat - конкатенация строк

substring - получение подстроки ([Строка], [ с какого символа], [сколько символов])

obj - формирование объекта, нечетные аргументы - имена свойств, четные - значения

агрегация:

max, min, avg, sum, count

Все функции агрегации принимают следующие аргументы:

либо

[$Имя атрибута коллекции], [Имя агрегируемого атрибута], [функция фильтрации элементов коллекции]

либо

[Имя класса], [Имя агрегируемого атрибута], [Объект фильтра сформированный функцией obj соответствующий нотации фильтров mongodb]

1 - указывает на уникальность объекта, то есть позволяет для функций агрегации производить подсчет только по уникальным объектам

\n - перенос на другую строку

Пример:

"formula": {
        "merge": [
          "$atr1",
          "atr2.name",
          null,
          1,
          "\n"
        ]
      },

Автоприсвоение и получение значения атрибута в вычисляемом выражении

  1. Чтобы вычисляемое выражение не выполнялось при открытии формы создания, у атрибута надо выставить autoassigned: true. Тогда выражения будут вычислены непосредственно перед сохранением объекта. Это актуально при использовании функции next в вычислениях, так как не всегда необходимо извлекать очередное значение последовательности при каждом открытии формы создания.
  2. Значения по умолчанию рассчитываются до записи объекта в БД, то есть на этапе их вычисления в простых автоприсваемых атрибутах еще ничего нет.
  3. Функция next($id) (если в $id задано значение) будет всегда возвращать 1, так как для каждого объекта будет создаваться отдельная последовательность, из которой выбирается только первое значение.