过滤猫鼬中两个种群的空值

问题描述 投票:1回答:1

主要目标

我想检索翻译,将它们投影为术语(Term),并且两者之间具有单一关系(Relation)。

状态

我正在描述术语Term。将其视为单词(通常是名词)。

const TermSchema: Schema = new Schema({
  _id:  mongoose.Schema.Types.ObjectId,  
  term: { type: String, required: true },
  lang: { type: String, required: true},
  relations: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Relation' }],
});

export default mongoose.model<Term & mongoose.Document>('Term', TermSchema);

Relation模式描述了这些术语的关系。

const RelationSchema: Schema = new Schema({
    _id:  mongoose.Schema.Types.ObjectId,  
    relationType: { type: String, required: true, default: RelationEnum.TRANSLATION },
    termSrc: { type: mongoose.Schema.Types.ObjectId, ref: 'Term'  },
    termTrg: { type: mongoose.Schema.Types.ObjectId, ref: 'Term'  },    
  });

export default mongoose.model<Relation & mongoose.Document>('Relation', RelationSchema);

我想从一种语言组合中检索所有翻译。假设德语(de)和阿拉伯语(ar)。那是:

  1. 使用值relationTypeRelationEnum.TRANSLATION检索所有关系。
  2. 填充termSrc,其中语言是de或ar。
  3. 在语言为de或ar时填充termTrg。

这促使我写了以下猫鼬的声明。

var query = Relation.find({relationType: 'TRANSLATION' }, null)
                .populate( {path: 'termSrc', select: 'term lang', model: Term, match: {lang: {$in: ['ar', 'de']}}})
                .populate( {path: 'termTrg', select: 'term lang', model: Term, match: {lang: {$in: ['ar', 'de']}}});

在大多数情况下,肯定会达到我的目标。这是单个记录的理想示例,该示例将返回。

    {
        "_id": "41224d776a326fb40f000023",
        "relationStatus": "QUALIFIED",
        "termSrc": {
            "_id": "41224d776a326fb40f000021",
            "term": "Verhaftung",
            "lang": "de"
        },
        "termTrg": {
            "_id": "41224d776a326fb40f000022",
            "term": "اعتقالات",
            "lang": "ar"
        }
    }

问题陈述

由于termSrc和termTrg的总体是完全独立的(就像一个OR语句,是一个析取运算,所以它也将包括只有一个过滤器适用于该总体的关系。因此,查询还将返回法语-阿拉伯语翻译的记录。当然,像在此示例记录中一样,将fr项设置为null(因为我们寻找'ar', 'de')。

   {
        "_id": "01224d776a326fb40f000050",
        "relationStatus": "QUALIFIED",
        "termSrc": null,
        "termTrg": {
            "_id": "01224d776a326fb40f000034",
            "term": "تقالا",
            "lang": "ar"
        }
    }

这不是我想要的,并且会导致产后清理。我只想要de-ar和ar-de翻译。

正如我的主要目标所表达的,我只希望在填充两个术语的地方都返回关系(它们都不应该是null)。

  • 可以1)运行find,然后都运行populate,然后2)对中间结果运行过滤器,以避免null记录吗?
  • 如果无法通过中间查询来完成,那么如何使用聚合来实现这一点,从而过滤termSrc和termTrg中具有空记录的所有关系?
mongodb mongoose aggregation-framework mongoose-schema mongoose-populate
1个回答
1
投票

您可以使用$lookup以下版本

  Relation.aggregate([
    { $match: { relationType: "TRANSLATION" } },
    {
      $lookup: {
        from: Term.collection.name,
        let: { termSrc: "$termSrc" },
        pipeline: [{ $match: { $expr: { $eq: ["$_id", "$$termSrc"] } } }],
        as: "termSrc"
      }
    },
    { $unwind: "$termSrc" },
    {
      $lookup: {
        from: Term.collection.name,
        let: { termTrg: "$termTrg" },
        pipeline: [{ $match: { $expr: { $eq: ["$_id", "$$termTrg"] } } }],
        as: "termTrg"
      }
    },
    { $unwind: "$termTrg" }
  ]);
© www.soinside.com 2019 - 2024. All rights reserved.