Fast implementation of multiple related models properties fetching & mixing to your model.
Быстрая реализация нескольких связанных извлечений свойств моделей и смешивание к вашей модели.
-
DB agnostic.
-
flexible query condition
-
one DB query per subscription.
-
all queries running parallel, starting at same moment, you choose then
-
No loops, stream based.
-
zero dependencies
-
DB агностика.
-
гибкое условие запроса
-
один DB запрос на подписку.
-
все запросы идут параллельно, начинаясь в одно и то же время, которое вы выьерете потом
-
Нет петель, основанных на потоке.
-
нулевая зависимость
You create subscription
around your related model with makeSubscription(model, options)
Вы создаёте subscription
вокруг вашей родственной модели с makeSubscription(model, options)
You can create any count of subscriptions you need. Вы можете создать любое колличество подписок, которое вам необходимо.
Then you can to subscription.add(target)
target objects you want to mix in
properties from related model data.
Затем вы можете subscription.add(target)
целевые объекты, которые вы хотите смешать в
свойства из родственной модели данных.
After you've added all needed targets to all subscriptions
you can anytime run
fillSubscriptions()
После того, как вы добавили всё, что необходимо, цели ко всем subscriptions
вы можете в любое время
перейти в fillSubscriptions()
fillSubscriptions()
assigns data as it goes via stream with auto parallelization
if multiple subscriptions
created. One query per subscription
is executed.
fillSubscriptions()
назначит данные, так как это идёт через поток с авто распараллеливанием
если умножить созданные subscriptions
. Один запрос на subscription
выполнен.
It generates mongo condition. If you return from
options.getCondition(target)
scalar value then is generated $in
query. I
to query your source,
Он производит монго состоятие. Если вы вернётесь из options.getCondition(target)
скалярное значение затем генерируется в $in
запрос.
чтобы запросить ваш источник,
Mongo query generation is just default behavior, you can alter it as you want.
Генерация монго запросов происходит по умолчанию, вы можете изменить это так, как захотите.
npm i subscribe-for-data subscribe-for-data-from-mongoose
const mongoosePlugin = require('subscribe-for-data-from-mongoose');
const {
makeSubscription, fillSubscriptions
} = require('subscribe-for-data').use(mongoosePlugin);
By default it works with mongoose. This behavior can be easily overriden by
setting custom getStream
option callback.
По умолчанию это работает с мангуста. Этот режим может быть легко отменён
установкой пользовательской getStream
настройки отозвать.
const mongoosePlugin = require('subscribe-for-data-from-mongoose');
const { makeSubscription, fillSubscriptions } = require('subscribe-for-data').use(mongoosePlugin);
const RootModel = require('./MainModel');
const RelatedModel = require('./RelatedModel');
const AnotherRelatedModel = require('./AnotherRelatedModel');
(async () => {
const relatedSubscription = makeSubscription(RelatedModel, { // single field attach
targetField: 'position', // key of property to be created on roots
foreignField: 'root_id', // field to build condition against
sourceField: 'position'
});
const anotherRelatedSubscription = makeSubscription(AnotherRelatedModel, { // something completely different
getCondition({ mysteriousTimestamp, type }) {
return { type, updatedAt: { $gt: mysteriousTimestamp} };
},
assignData(root, { someField, otherType }) {
(root.someFields = root.someField || []).push(someField);
(root.otherTypes = root.otherTypes || new Set()).add(otherType);
},
});
const roots = [];
await RootModel.find({}).cursor().eachAsync((root) => {
[relatedSubscription, anotherRelatedSubscription]
.forEach(subscription => subscription.add(root)); // subscribed
roots.push(root);
});
await fillSubscriptions(); // 2 DB queries executed in parallel, no loops then
console.log(roots[0]);
})();
Expected output:
Ожидаемый результат:
{
"_id": "000000",
"position": 42,
"someFields": [2, 5, 8, 5],
"otherTypes": [23, 42, 78]
}
- SubscribeForData :
object
- .makeSubscription(source, options) ⇒
Object
- .fillSubscriptions() ⇒
Promise
- .assignDefaultOptions(mixin)
- .makeSubscription(source, options) ⇒
- assignData :
function
- getKey ⇒
*
- extractKey ⇒
*
- getCondition ⇒
*
- getDataHandler ⇒
function
- getAddingMethod ⇒
function
- getStream :
function
subscribe-for-data
- SubscribeForData :
object
- .makeSubscription(source, options) ⇒
Object
- .fillSubscriptions() ⇒
Promise
- .assignDefaultOptions(mixin)
- .makeSubscription(source, options) ⇒
Creates subscription for related model data
Param | Type | Description |
---|---|---|
source | Object |
Source model |
options | Object |
Options |
options.targetField | String |
field data to be saved into (optional) |
options.baseCondition | Object |
Base condition |
options.defaultValue | * |
Default value for field |
options.getKey | getKey |
Callback which returns unique key from target model (model.id by default) |
options.getCondition | getCondition |
returns condition, using target model (model.id by default) |
options.extractKey | extractKey |
returns unique key of target model from foreign model |
options.isMultiple | Boolean |
if one to many relation |
options.useEachAsync | Boolean |
only for mongoose cursor |
options.parallel | Number |
parallel parameter for eachAsync if useEachAsync is true |
options.foreignField | String |
If getCondition returns scalar values this field will be used for $in |
options.sourceField | String |
field to use of foreign model |
options.assignData | assignData |
Do model filling by itself, otherwise use targetField |
options.getStream | getStream |
returns stream from source and condition (using mongoose model by default) |
options.getDataHandler | getDataHandler |
Get data handler for processing related models |
options.getAddingMethod | getAddingMethod |
Get add() method of future subscription |
Fill subscribed targets
change default options
Param |
---|
mixin |
Assigns data from foreign model to target
Назначает данные от иностранной модели к цели
Param | Type | Description |
---|---|---|
target | Object |
your target model |
foreign | Object |
foreign model |
get unique identifier of target for internal indexing
даёт уникальный идентификатор цели для внутренней индексации
Returns: *
- target identifier
возвращает: *
- целевой идентификатор
Param | Type | Description |
---|---|---|
target | Object |
your target model |
get unique identifier of target from foreign model
даёт уникальный идентификатор цели из внешней модели
Returns: *
- target identifier
возвращает: *
- целевой идентификатор
Param | Type | Description |
---|---|---|
foreign | Object |
Foreign model data |
get condition
получить условие
Returns: *
- condition, can be scalar or object
Возвращает: *
- условие, которое может быть скалярным или обЪектом
Param | Type | Description |
---|---|---|
target | Object |
your target model |
get foreign data handler
получить обработчик внешних данных
Returns: function
- Callback handling data assignment
Возвращает: function
- Обратный вызов назначенных данных
Param | Type | Description |
---|---|---|
options | Object |
Options |
options.targets | Object |
targets index |
options.targetField | String |
field data to be saved into |
options.extractKey | extractKey |
returns unique key of target model from foreign model |
options.isMultiple | Boolean |
if one to many relation |
options.sourceField | String |
field to use of foreign model |
options.assignData | assignData |
Do model filling by itself, otherwise use targetField |
get future subscription.add()
method
Returns: function
- Callback handling data assignment
Возвращает: function
- Обратный вызов назначенных данных
Param | Type | Description |
---|---|---|
options | Object |
Options |
options.targets | Object |
targets index |
options.getKey | getKey |
Callback which returns unique key from target model (model.id by default) |
options.getCondition | getCondition |
returns condition, using target model (model.id by default) |
options.defaultValue | * |
Default value for field |
options.targetField | String |
field data to be saved into |
options.condition | object |
DB Query condition, being prepared |
options.extractKey | extractKey |
returns unique key of target model from foreign model |
options.foreignField | String |
If getCondition returns scalar values this field will be used for $in |
options.inner | Array |
Internal array for condition storing |
get stream from model using condition
получить поток из модели, используя условие
Param | Description |
---|---|
source | Source model |
condition | Query condition |