MongoDB 使用聚合框架的条件 $lookup
MongoDB conditional $lookup with aggregration framework
我正在尝试使用聚合框架进行条件查找。在我的本地和国外 collections 我有两个字段:fieldA 和 fieldB。如果 fieldA != 0 我的 $lookup 应该是:
{ from: 'collectionA', localField: 'fieldA', foreignField: 'fieldA', as: 'agg' }
否则,如果 fieldA = 0,我的 $lookup 应该是:
{ from: 'collectionA', localField: 'fieldB', foreignField: 'fieldB', as: 'agg' }
是否可以将这些条件与单个 $lookup 结合起来?
这不太可能 OOB,但您可以通过多种方式解决这个问题。
例如根据这个条件添加一个新的“临时”字段:
db.colleciton.aggregate([
{
$lookup: {
from: 'collectionA',
let: {
fieldA: "$fieldA", fieldB: "$fieldB"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
{
$cond: [
{
$eq: [
'$$fieldA',
0,
],
},
'$$fieldB',
'$$fieldA',
],
},
{
$cond: [
{
$eq: [
'$$fieldA',
0,
],
},
'$fieldB',
'$fieldA',
],
}
],
},
},
},
],
as: 'agg',
},
}
])
这种方法的问题是索引不会用于查找旧的 Mongo 版本,这在某些情况下可能是至关重要的。
您可以像这样解决性能问题:
db.collection.aggregate([
{
$facet: {
one: [
{
$match: {
fieldA: { $ne: 0 },
},
},
{
$lookup: { from: 'collectionA', localField: 'fieldA', foreignField: 'fieldA', as: 'agg' },
},
{
$match: {
'agg.0': { $exists: true },
},
},
],
two: [
{
$match: {
fieldA: { $eq: 0 },
},
},
{
$lookup: { from: 'collectionA', localField: 'fieldB', foreignField: 'fieldB', as: 'agg' },
},
{
$match: {
'agg.0': { $exists: true },
},
},
],
},
},
{
$addFieldS: {
combined: {
$concatArrays: [
'$one',
'$two',
],
},
},
},
{
$unwind: '$combined',
},
{
$replaceRoot: {
newRoot: "$combined"
},
},
]);
虽然这里有一些开销,但它仍然比非索引查找更快。
我正在尝试使用聚合框架进行条件查找。在我的本地和国外 collections 我有两个字段:fieldA 和 fieldB。如果 fieldA != 0 我的 $lookup 应该是:
{ from: 'collectionA', localField: 'fieldA', foreignField: 'fieldA', as: 'agg' }
否则,如果 fieldA = 0,我的 $lookup 应该是:
{ from: 'collectionA', localField: 'fieldB', foreignField: 'fieldB', as: 'agg' }
是否可以将这些条件与单个 $lookup 结合起来?
这不太可能 OOB,但您可以通过多种方式解决这个问题。
例如根据这个条件添加一个新的“临时”字段:
db.colleciton.aggregate([
{
$lookup: {
from: 'collectionA',
let: {
fieldA: "$fieldA", fieldB: "$fieldB"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
{
$cond: [
{
$eq: [
'$$fieldA',
0,
],
},
'$$fieldB',
'$$fieldA',
],
},
{
$cond: [
{
$eq: [
'$$fieldA',
0,
],
},
'$fieldB',
'$fieldA',
],
}
],
},
},
},
],
as: 'agg',
},
}
])
这种方法的问题是索引不会用于查找旧的 Mongo 版本,这在某些情况下可能是至关重要的。
您可以像这样解决性能问题:
db.collection.aggregate([
{
$facet: {
one: [
{
$match: {
fieldA: { $ne: 0 },
},
},
{
$lookup: { from: 'collectionA', localField: 'fieldA', foreignField: 'fieldA', as: 'agg' },
},
{
$match: {
'agg.0': { $exists: true },
},
},
],
two: [
{
$match: {
fieldA: { $eq: 0 },
},
},
{
$lookup: { from: 'collectionA', localField: 'fieldB', foreignField: 'fieldB', as: 'agg' },
},
{
$match: {
'agg.0': { $exists: true },
},
},
],
},
},
{
$addFieldS: {
combined: {
$concatArrays: [
'$one',
'$two',
],
},
},
},
{
$unwind: '$combined',
},
{
$replaceRoot: {
newRoot: "$combined"
},
},
]);
虽然这里有一些开销,但它仍然比非索引查找更快。