Legacy API
This page documents the legacy @logic-bee/flow-query package, which has been superseded by @logic-bee/data-flow. See Mutations, Advanced, and the migration guide for equivalents. New code should use the new API.
Advanced Operations
Advanced operations use flowQuery and flowData to configure granular field-level mutations on documents.
Getting a Flow Data Instance
First, set up your flow query, then call .flowData() to begin building operations:
// -->Set: the query to a specific document id
const flowQuery = flowCollection.docs.flowQuery()
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.docId(bob.dataPayload.docId);
Individual Operations
setData()
// -->Set: data for document body
const flowData = flowQuery.flowData().setData({ 'name': 'Monkey Man' });
patchDocument()
// -->Set: the data body of the document and do an update patch
const flowData = flowQuery.flowData().setData(bob.dataPayload.data).patchDocument();
status()
// -->Set: a new status for the document
const flowData = flowQuery.flowData().status('complete', 'data');
push()
// -->Push: a value to the array in a nested document
const flowData = flowQuery.flowData().push('eventLog', { eventName: 'flight_to_mars' });
pull()
// -->Pull: remove all the values that match the filter
const flowData = flowQuery.flowData().pull('eventLog', { eventName: 'flight_to_mars' });
pullAll()
// -->Pull: all values that match the filter
const flowData = flowQuery.flowData().pullAll('eventLog', { eventName: 'flight_to_mars' });
updateArray()
Update values inside an array — optionally with a filter:
// -->Update: all the values in an array without any filters
const flowData = flowQuery.flowData().updateArray('eventLog', { eventName: 'flight_to_mars' });
// -->Update: only values matching a filter
const flowData = flowQuery.flowData().updateArray('eventLog', { createdAt: naoDateTime() }, { filter: { eventName: 'flight_to_mars' } });
slice()
// -->Slice: an array to keep only N items
const flowData = flowQuery.flowData().slice('eventLog', 20);
rename()
// -->Rename: a field
flowData = flowData.rename({ 'data.paypal': 'data.spacex' });
set()
// -->Set: specific values
flowData = flowData.set({ 'data.maxScore': 120, 'data.minScore': 110, 'data.avgScore': 100 });
unset()
// -->Unset: values of specific keys
flowData = flowData.unset(['data.name'])
min()
// -->Min: set minimum value of a specific field
flowData = flowData.min({ 'data.minScore': 110 })
max()
// -->Max: set maximum value of a specific field
flowData = flowData.max({ 'data.avgScore': 90 })
Query Utilities
clone()
Clone a query and optionally reset it:
// -->Query: define the original query
const originalQuery$ = flowCollection.docs.flowQuery()
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.query({ 'data.name': 'John' });
// -->Clone: the original query and apply a new query
const cloneQuery$ = originalQuery$.clone(true).query({ 'data.name': 'George' });
If you pass true as a parameter, it will reset the old query (limit, query, docId, docIds) and apply the new one.
resetQuery()
const originalQuery$ = flowCollection.docs.flowQuery()
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.query({ 'data.name': 'John' });
// -->Reset: the original query and create a new query object
const resetQuery$ = originalQuery$.resetQuery();
resetLimit()
const originalQuery$ = flowCollection.docs.flowQuery()
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.limit(10);
// -->Reset: remove limit/skip from the query
const resetLimit$ = originalQuery$.resetLimit();
resetProjection()
const originalQuery$ = flowCollection.docs.flowQuery()
.user(bob.flowUser)
.flowOptions(bob.naoQueryOptions)
.projection({ 'data.name': 1, 'data.description': 1 });
// -->Reset: remove projections from the query
const resetProjection$ = originalQuery$.resetProjection();
Chaining Multiple Operations
Operations can be chained together for complex mutations in a single call.
Set, pull, slice, status
// -->Data: set a new status, update name, pull from event log, keep first 20 values
const flowData = flowQuery.flowData()
.status('complete', 'data')
.set({ 'data.name': 'Monkey Man' })
.pull('eventLog', { eventName: 'flight_to_mars' })
.slice('eventLog', 20);
Push, rename
// -->Generate: an array with 150 values
data$ = newArray(150).map(v => ({ name: `Ion ${v}`, id: v, grade: v }));
// -->Data: rename 1 field and push an object into the eventLog array
flowData = flowData.rename({ 'data.paypal': 'data.spacex' }).push('data.eventLog', data$);
// -->Generate: 150 notifications
data$ = newArray(150).map(v => ({ notification: `No ${v}`, id: v, seen: false }));
// -->Data: push the values to the data.notifications array
flowData.push('data.notifications', data$);
Update multiple arrays
// -->Data: Set all notifications matching different filter criteria
flowData
.updateArray('data.notifications', { seen: true }, { filter: { id: 1 } })
.updateArray('data.notifications', { seen: true }, { filter: { id: { $in: [4, 5, 6] } } })
.updateArray('data.notifications', { seen: true }, { filter: { id: { $gte: 25, $lte: 35} } });
Pull, push, set, unset, slice
// -->Complex: remove notifications, set status, push event, unset name, slice
flowData
.pull('data.notifications', { id: { $in: [4, 5, 9] } })
.push('data.eventLog', { event: 'update', activity: 'clean notifications' }, { maxLength: 49 })
.status('active', 'data')
.unset(['data.name'])
.set({ 'data.maxScore': 120, 'data.minScore': 110, 'data.avgScore': 100 })
.slice('data.eventLog', 50);
Set, min, max
// -->Data: Set the name, update the scores with min/max
flowData
.set({ 'data.name': 'John' })
.min({ 'data.minScore': 110 })
.max({ 'data.maxScore': 187 })
.max({ 'data.avgScore': 90 })