mongodb - MongoDB 聚合 - 读取文档的运算符
问题描述
由于 Mongo 仅支持每个聚合管道(在第一阶段内)的一个 字段,这意味着您无法执行逻辑 AND,因为您无法获得多个搜索的结果。$text
$match
$and
$text
// Fails due to "too many text expressions"
db.Employees.aggregate([
{$match: {$and: [
{$text: {$search: "senior"}},
{$text: {$search: "manager"}}
]}}
])
因此,我需要执行多个单独$text
的搜索,将结果合并到我的 NodeJS 代码中,然后将该结果集传递回聚合管道以进行进一步处理(例如$addFields
、$match
、$sort
)。
有没有办法做类似...
let results1 = db.Employees.find({"$text":{"$search":"senior"}}, {"score":{"$meta":"textScore"}})
let results2 = db.Employees.find({"$text":{"$search":"manager"}}, {"score":{"$meta":"textScore"}})
let combinedResults = _.intersectionWith(results1, results2, _.isEqual)
let finalResults = /* pass combinedResults into aggregation pipeline and execute it */
与$out 运算符相反的东西,我在结果集中读取。
如果有帮助,我正在使用 NestJS 和 Mongoose。
解决方案
有限制,$text
你已经知道了,
如果您的字段有限,则有一个选项,使用$regexMatch,我不确定在多少字段中有文本索引,但是您可以将匹配条件与$and
多个字段的运算符结合使用,
示例数据:
[
{ _id: 1, f1: "senior", f2: "manager" },
{ _id: 2, f1: "junior", f2: "manager" },
{ _id: 3, f1: "fresher", f2: "developer" },
{ _id: 4, f1: "manager", f2: "senior" }
]
聚合查询一:
$addFields
在布尔值中添加新字段matchResult
以匹配状态
db.collection.aggregate([
{
$addFields: {
matchResult: {
$and: [
- 第一个
$or
条件匹配 iff1
orf2
fields matchsenior
then returntrue
other wise returnfalse
{
$or: [
{ $regexMatch: { input: "$f1", regex: "senior", options: "x" } },
{ $regexMatch: { input: "$f2", regex: "senior", options: "x" } }
]
},
- 第二个
$or
条件匹配 iff1
orf2
fields matchmanager
then returntrue
other wise returnfalse
{
$or: [
{ $regexMatch: { input: "$f1", regex: "manager", options: "x" } },
{ $regexMatch: { input: "$f2", regex: "manager", options: "x" } }
]
}
]
}
}
},
$match
条件返回结果matchResult
等于true
{ $match: { matchResult: true } }
])
聚合查询2:
- 如果您不使用数组字段,那么这是一种排序方式,您可以直接将所有字段连接到一个字段上,这里我已经合并
f1
并f2
带有空格allField
db.collection.aggregate([
{
$addFields: {
allField: { $concat: ["$f1", " ", "$f2"] }
}
},
- 这将匹配
$and
两个单词匹配的条件,如果两者都为真,则返回真,否则为假
{
$addFields: {
matchResult: {
$and: [
{ $regexMatch: { input: "$allField", regex: "senior", options: "x" } },
{ $regexMatch: { input: "$allField", regex: "manager", options: "x" } }
]
}
}
},
$match
条件返回结果matchResult
等于true
{ $match: { matchResult: true } }
])
注意:这是有限字段的替代方法,但如果超过 5 个字段进行成像,则会影响查询的速度和性能。
推荐阅读
- django - Django没有从ajax接收数据
- javascript - 无论如何我可以将变量设置为一系列数字并将其包含在函数中吗?(javascript)
- ios - MKMapView userTrackingMode 在 SwiftUI 中重置
- c# - 如何防止任何用户删除文件
- python - 需要一个 Python 程序单数到复数
- python - 如何 pip 安装需要构建 cython 代码的包?
- javascript - reactJS - 使用 Axios GET 请求的 useEffect() 空响应
- javascript - 箭头函数不应返回赋值 Eslint
- python - 使用 pygame.Surface() 后 Pygame 精灵不会更新
- java - Spring MVC 'forward' 不适用于同一 URI 的 @PostMapping 和 @GetMapping 注解