English
Query operator, used to express a logical "AND" relationship, indicating that multiple query filter conditions need to be satisfied at the same time
and
has two use cases:
1. Used in the root query condition
At this time, multiple query conditions need to be passed in, which means that multiple complete query conditions need to be satisfied at the same time.
const dbCmd = db.command
let res = await db.collection('todo').where(dbCmd.and([
{
progress: dbCmd.gt(50)
},
{
tags: 'cloud'
}
])).get()
However, the above query conditions composed of and
are unnecessary, because the fields of the incoming object implicitly form an "and" relationship. The above conditions are equivalent to the following more concise writing:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.gt(50),
tags: 'cloud'
}).get()
It is usually necessary to explicitly use and
when there are cross fields or operations
2. Used in field query conditions
Multiple query operators or constants need to be passed in, indicating that the field must meet or match the given conditions.
As shown in the following preamble, "progress field value is greater than 50 and less than 100"
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.and(dbCmd.gt(50), dbCmd.lt(100))
}).get()
The same condition can also be expressed in postfix:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.gt(50).and(dbCmd.lt(100))
}).get()
Note that Command
can also directly call other Command
in a chain by default, which by default means the AND operation of multiple Command
, so the above code can also be simplified as:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.gt(50).lt(100)
}).get()
The method accepts two ways of passing parameters, one is to pass in an array parameter, the other is to pass in multiple parameters, the effect is the same.
// pass in the array
function and(expressions: Expression[]): Command
// pass in multiple parameters
function and(...expressions: Expression[]): Command
The query operator is used to express a logical "or" relationship, indicating that multiple query filter conditions need to be satisfied at the same time. The OR instruction has two usages. One is to perform the "OR" operation of field values, and the other is to perform the "OR" operation across fields.
The "or" operation of field values refers to specifying a field value as one of multiple values.
For example, to filter out todos with progress greater than 80 or less than 20:
Streaming writing:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.gt(80).or(dbCmd.lt(20))
}).get()
Prefix:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.or(dbCmd.gt(80), dbCmd.lt(20))
}).get()
Prefix also accepts an array:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.or([dbCmd.gt(80), dbCmd.lt(20)])
}).get()
The "or" operation across fields refers to the condition "or", which is equivalent to passing in multiple where statements, and only one of them can be satisfied.
To filter out todos with progress greater than 80 or marked as completed:
const dbCmd = db.command
let res = await db.collection('todo').where(dbCmd.or([
{
progress: dbCmd.gt(80)
},
{
done: true
}
])).get()
The method accepts two ways of passing parameters, one is to pass in an array parameter, the other is to pass in multiple parameters, the effect is the same.
// pass in the array
function or(expressions: Expression[]): Command
// pass in multiple parameters
function or(...expressions: Expression[]): Command
The query operator is used to express a logical "not" relationship, which means that the specified conditions need not be met.
For example, to filter out todos whose progress is not equal to 100:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.not(dbCmd.eq(100))
}).get()
not
can also be used with other logical instructions, including and
, or
, nor
, not
, such as or
:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.not(dbCmd.or([dbCmd.lt(50), dbCmd.eq(100)]))
}).get()
The query operator is used to express a logical "Neither" relationship, indicating that all the specified conditions need not be met. If there is no corresponding field in the record, the condition is satisfied by default.
Filter out todos whose progress is neither less than 20 nor greater than 80:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.nor([dbCmd.lt(20), dbCmd.gt(80)])
}).get()
The above will also filter out the records without the progress
field. If you want to require the progress
field to exist, you can use the exists
command:
const dbCmd = db.command
let res = await db.collection('todo').where({
progress: dbCmd.exists().nor([dbCmd.lt(20), dbCmd.gt(80)])
// progress: dbCmd.exists().and(dbCmd.nor([dbCmd.lt(20), dbCmd.gt(80)]))
}).get()
Filter out records whose progress
is not less than 20 and whose tags
array does not contain the miniprogram
string:
const dbCmd = db.command
db.collection('todo').where(dbCmd.nor([{
progress: dbCmd.lt(20),
}, {
tags: 'miniprogram',
}])).get()
The above will filter records that meet one of the following conditions:
progress
is not less than 20 and the tags
array does not contain the miniprogram
string 3. progress
is not less than 20 and the tags
field does not exist 5. The progress
field does not exist and the tags
array does not contain miniprogram
string 7. progress
is not less than 20 and the tags
field does not exist
If the progress
and tags
fields are required to exist, the exists
directive can be used:const dbCmd = db.command
let res = await db.collection('todo').where(
dbCmd.nor([{
progress: dbCmd.lt(20),
}, {
tags: 'miniprogram',
}])
.and({
progress: dbCmd.exists(true),
tags: dbCmd.exists(true),
})
).get()
The method accepts two ways of passing parameters, one is to pass in an array parameter, the other is to pass in multiple parameters, the effect is the same.
// pass in the array
function nor(expressions: Expression[]): Command
// pass in multiple parameters
function nor(...expressions: Expression[]): Command
Query filter conditions, indicating that the field is equal to a value. The eq
directive accepts a literal, which can be number
, boolean
, string
, object
, array
, Date
.
For example, to filter out all the articles published by oneself, in addition to the method of passing objects:
const openID = 'xxx'
let res = await db.collection('articles').where({
_openid: openID
}).get()
You can also use the command:
const dbCmd = db.command
const openID = 'xxx'
let res = await db.collection('articles').where({
_openid: dbCmd.eq(openid)
}).get()
Note that the eq
directive has more flexibility than the object method and can be used to indicate that a field is equal to an object, such as:
// This notation means match stat.publishYear == 2018 and stat.language == 'zh-CN'
let res = await db.collection('articles').where({
stat: {
publishYear: 2018,
language: 'zh-CN'
}
}).get()
// This way of writing means that the stat object is equal to { publishYear: 2018, language: 'zh-CN' }
const dbCmd = db.command
let res = await db.collection('articles').where({
stat: dbCmd.eq({
publishYear: 2018,
language: 'zh-CN'
})
}).get()
Query filter conditions, indicating that the field is not equal to a value. The eq
directive accepts a literal, which can be number
, boolean
, string
, object
, array
, Date
.
Indicates that the field is not equal to a value, as opposed to eq
Query filter operator, indicating that it needs to be less than the specified value. A Date
object can be passed in for date comparison.
Find todos with progress less than 50
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.lt(50)
})
.get()
Query filter operator, indicating that it must be less than or equal to the specified value. A Date
object can be passed in for date comparison.
Find todos with progress less than or equal to 50
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.lte(50)
})
.get()
Query filter operator, indicating that it must be greater than the specified value. A Date
object can be passed in for date comparison.
Find todos with progress greater than 50
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.gt(50)
})
.get()
Query filter operator, indicating that it must be greater than or equal to the specified value. A Date
object can be passed in for date comparison.
Find todos with progress greater than or equal to 50
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.gte(50)
})
.get()
Query filter operator, indicating that the value is required to be in the given array.
Find todos with progress of 0 or 100
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.in([0, 100])
})
.get()
Query filter operator, indicating that the required value is not in the given array.
Find todos whose progress is not 0 or 100
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.nin([0, 100])
})
.get()
Check if field exists
Find records where tags field exists
const dbCmd = db.command
let res = await db.collection('todos').where({
tags: dbCmd.exists(true)
})
.get()
Query filter operator, given the divisor divisor and remainder remainder, when the field is required as the dividend value % divisor = remainder.
Find records for fields whose progress is a multiple of 10
const dbCmd = db.command
let res = await db.collection('todos').where({
progress: dbCmd.mod(10, 0)
})
.get()
Array query operator. A query filter for array fields that requires all elements of a given array to be contained in the array field.
Find records whose tags array field contains both cloud and database
const dbCmd = db.command
let res = await db.collection('todos').where({
tags: dbCmd.all(['cloud', 'database'])
})
.get()
If the array element is an object, you can use dbCmd.elemMatch
to match part of the field of the object
Suppose there is a field places
defined as follows:
{
"type": string
"area": number
"age": number
}
Find out that the array field contains at least one element satisfying "area greater than 100 and age less than 2" and one element satisfying "type is mall and age greater than 5"
const dbCmd = db.command
let res = await db.collection('todos').where({
places: dbCmd.all([
dbCmd.elemMatch({
area: dbCmd.gt(100),
age: dbCmd.lt(2),
}),
dbCmd.elemMatch({
type: 'mall',
age: dbCmd.gt(5),
}),
]),
})
.get()
Query filter conditions for array fields that require at least one element in the array that satisfies all conditions given by elemMatch
Suppose the collection example data is as follows:
{
"_id": "a0",
"city": "x0",
"places": [{
"type": "garden",
"area": 300,
"age": 1
}, {
"type": "theatre",
"area": 50,
"age": 15
}]
}
Find at least one element in the places
array field that satisfies "area greater than 100 and age less than 2"
const dbCmd = db.command
let res = await db.collection('todos').where({
places: dbCmd.elemMatch({
area: dbCmd.gt(100),
age: dbCmd.lt(2),
})
})
.get()
Note*: If you do not use elemMatch
and specify the condition directly as follows, it means that the area
field of at least one element in the places
array field is greater than 100 and the places
array field has at least one element. The age
field is less than 2:
const dbCmd = db.command
let res = await db.collection('todos').where({
places: {
area: dbCmd.gt(100),
age: dbCmd.lt(2),
}
})
.get()
Suppose the collection example data is as follows:
{
"_id": "a0",
"scores": [60, 80, 90]
}
Find at least one element in the scores
array field that satisfies "greater than 80 and less than 100" at the same time
const dbCmd = db.command
let res = await db.collection('todos').where({
scores: dbCmd.elemMatch(dbCmd.gt(80).lt(100))
})
.get()
The update operator is used for the query filter condition of the array field, and the length of the array is required to be a given value
Find all records with tags array field length 2
const dbCmd = db.command
let res = await db.collection('todos').where({
places: dbCmd.size(2)
})
.get()
Find records with field values near a given point in order from nearest to farthest.
Geographical index needs to be established on the query field
Find records within 1km to 5km of a given location
const dbCmd = db.command
let res = await db.collection('restaurants').where({
location: dbCmd.geoNear({
geometry: new db.Geo.Point(113.323809, 23.097732),
minDistance: 1000,
maxDistance: 5000,
})
}).get()
Finds records whose field value is in the specified range, without sorting. The specified area must be a polygon (Polygon) or a collection of polygons (MultiPolygon).
Geographical index needs to be established on the query field
const dbCmd = db.command
const { Point, LineString, Polygon } = db.Geo
let res = await .collection('restaurants').where({
location: dbCmd.geoWithin({
geometry: new Polygon([
new LineString([
new Point(0, 0),
new Point(3, 2),
new Point(2, 3),
new Point(0, 0)
])
]),
})
}).get()
A circle can be constructed with centerSphere
instead of geometry
.
The definition of the value corresponding to centerSphere
is: [ [longitude, latitude], radius]
The radius needs to be measured in radians. For example, if a radius of 10km is required, divide the distance by the earth's radius of 6378.1km.
const dbCmd = db.command
let res = await db.collection('restaurants').where({
location: dbCmd.geoWithin({
centerSphere: [
[-88, 30],
10 / 6378.1,
]
})
}).get()
Find the records that intersect the graph for a given geographic location
Geographical index needs to be established on the query field
const dbCmd = db.command
const { Point, LineString, Polygon } = db.Geo
let res = await db.collection('restaurants').where({
location: dbCmd.geoIntersects({
geometry: new Polygon([
new LineString([
new Point(0, 0),
new Point(3, 2),
new Point(2, 3),
new Point(0, 0)
])
]),
})
}).get()
The query operator is used to use aggregate expressions in query statements. The method receives a parameter, which must be an aggregate expression.
expr
can be used to introduce aggregate expressions in an aggregatematch
pipeline stage 3. If an aggregate[match
](cf-database-aggregate#aggregate- match) phase is in the lookup
phase, the variables defined by the let
parameter in lookup
can be used in the expr
expression at this time. The specific example See specify multiple join conditions
in lookup
Example 5. expr
can be used to introduce aggregate expressions in ordinary query statements (where
)Suppose the data structure of the items
collection is as follows:
{
"_id": string,
"inStock": number, // 库存量
"ordered": number // 被订量
}
Find records where the quantity ordered is greater than the quantity in stock:
const dbCmd = db.command
const $ = dbCmd.aggregate
let res = await db.collection('items').where(dbCmd.expr($.gt(['$ordered', '$inStock']))).get()
Suppose the data structure of the items
collection is as follows:
{
"_id": string,
"price": number
}
Assuming that the price is less than or equal to 10, 20% off, and the price is greater than 10, 50% off, let the database query return the records whose price is less than or equal to 8 after the discount:
const dbCmd = db.command
const $ = dbCmd.aggregate
let res = await db.collection('items').where(dbCmd.expr(
$.lt([
$.cond({
if: $.gte(['$price', 10]),
then: $.multiply(['$price', '0.5']),
else: $.multiply(['$price', '0.8']),
})
,
8
])
).get()
Update operator, used to set the field equal to the specified value.
The advantage of this method over passing in a pure JS object is the ability to specify that the field is equal to an object
// The following method will only update style.color to red, not style to { color: 'red' }, that is, it will not affect other fields in style
let res = await db.collection('todos').doc('doc-id').update({
style: {
color: 'red'
}
})
// The following method updates the style to { color: 'red', size: 'large' }
let res = await db.collection('todos').doc('doc-id').update({
style: dbCmd.set({
color: 'red',
size: 'large'
})
})
The update operator is used to indicate the deletion of a field.
Remove the style field:
const dbCmd = db.command
let res = await db.collection('todos').doc('todo-id').update({
style: dbCmd.remove()
})
Update operator, atomic operation, used to indicate field auto-increment
When multiple users write at the same time, the fields are automatically incremented for the database, and there will be no situation where the latter will overwrite the former.
Increment the progress of a todo by 10:
const dbCmd = db.command
let res = await db.collection('todos').doc('todo-id').update({
progress: dbCmd.inc(10)
})
Update operator, atomic operation, used to instruct a field to multiply by a value
When multiple users write at the same time, for the database, the fields are multiplied by themselves, and there will be no situation where the latter will overwrite the former.
Multiply the progress of a todo by 10:
const dbCmd = db.command
let res = await db.collection('todos').doc('todo-id').update({
progress: dbCmd.mul(10)
})
Update operator, given a value, update only if the value is less than the current value of the field.
If field progress > 50, update to 50
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
progress: dbCmd.min(50)
})
The update operator, given a value, updates only if the value is greater than the current value of the field.
If field progress < 50, update to 50
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
progress: dbCmd.max(50)
})
Update operator, field rename. If you need to rename deeply nested fields, you need to use dot path notation. Fields of objects nested in arrays cannot be renamed.
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
progress: dbCmd.rename('totalProgress')
})
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
someObject: {
someField: dbCmd.rename('someObject.renamedField')
}
})
or:
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
'someObject.someField': dbCmd.rename('someObject.renamedField')
})
Array update operator. For a field whose value is an array, add one or more values to the array. or the field was originally empty, create the field and set the array as the incoming value.
position description
The each
parameter must also be present.
A non-negative number represents the position counted from the beginning of the array, starting at 0. If the value is greater than or equal to the length of the array, it is considered to be added at the end. Negative numbers represent the position counted from the end of the array, for example -1 means the position of the second-to-last element. If the absolute value of a negative value is greater than or equal to the length of the array, it is considered to be added from the head of the array.
sort instructions
The each
parameter must also be present. Give 1 for ascending order and -1 for descending order.
If the array element is a record, the format of { <field>: 1 | -1 }
is used to indicate the ascending and descending order according to what field in the record.
slice Description**
Requires that the each
parameter also exists
value | description |
---|---|
0 | Update field to empty array |
Positive numbers | Array retains only first n elements |
Negative | Array retains only last n elements |
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push(['mini-program', 'cloud'])
})
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: ['mini-program', 'cloud'],
position: 1,
})
})
Sort the entire array after insertion
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: ['mini-program', 'cloud'],
sort: 1,
})
})
Do not insert, just sort the array
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: [],
sort: 1,
})
})
If the field is an array of objects, it can be sorted according to the fields in the element object as follows:
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: [
{ name: 'miniprogram', weight: 8 },
{ name: 'cloud', weight: 6 },
],
sort: {
weight: 1,
},
})
})
Only keep the last 2 elements after insertion
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: ['mini-program', 'cloud'],
slice: -2,
})
})
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.push({
each: ['mini-program', 'cloud'],
position: 1,
slice: 2,
sort: 1,
})
})
Array update operator. For a field whose value is an array, delete the last element of the array. Only the last one can be deleted.
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.pop()
})
The array update operator, for a field whose value is an array, adds one or more values to the head of the array. or the field was originally empty, create the field and set the array as the incoming value.
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.unshift(['mini-program', 'cloud'])
})
The array update operator, for a field whose value is an array, deletes the element at the head of the array.
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.shift()
})
Array update operator. Given a value or a query condition, removes all elements in the array that match the given value or query condition.
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.pull('database')
})
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.pull(dbCmd.in(['database', 'cloud']))
})
Suppose there is a field places
The elements in the array are structured as follows
{
"type": string
"area": number
"age": number
}
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
places: dbCmd.pull({
area: dbCmd.gt(100),
age: dbCmd.lt(2),
})
})
Suppose there is a field cities
The element structure in the array is as follows
{
"name": string
"places": Place[]
}
Place
has the following structure:
{
"type": string
"area": number
"age": number
}
elemMatch
can be used to match object array fields nested inside object array places
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
cities: dbCmd.pull({
places: dbCmd.elemMatch({
area: dbCmd.gt(100),
age: dbCmd.lt(2),
})
})
})
Array update operator. Given a value or a query condition, removes all elements from the array that match the given value. The difference from pull
is that only constant values can be specified, and an array is passed in.
Remove all database and cloud strings from tags
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.pullAll(['database', 'cloud'])
})
Array update operator. Atomic operation. Given one or more elements, add them to the array unless they already exist in the array.
If the tags array does not contain database, add it
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.addToSet('database')
})
You need to pass in an object, which has a field each
whose value is an array, and each element is the element to be added
const dbCmd = db.command
let res = await db.collection('todos').doc('doc-id').update({
tags: dbCmd.addToSet({
$each: ['database', 'cloud']
})
})