主要目标
我想检索翻译,将它们投影为术语(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
)。那是:
relationType
的RelationEnum.TRANSLATION
检索所有关系。这促使我写了以下猫鼬的声明。
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
)。
find
,然后都运行populate
,然后2)对中间结果运行过滤器,以避免null
记录吗?您可以使用$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" }
]);