mongodb - 在 Mongoose 中过滤两个种群的空值
问题描述
主要目标
我想检索翻译,这些翻译被投影为术语 ( 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
检索与value的所有关系RelationEnum.TRANSLATION
。- 填充语言为 de 或 ar 的 termSrc。
- 填充语言为 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 中具有空记录的所有关系?
解决方案
您可以使用以下$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" }
]);
推荐阅读
- php - PHP.ini 思考设置与声明 strict_types 冲突
- r - 是否可以使用 actionButton 清除 ShinyApp 中显示的输出
- html - 修复独立于目录的 URL
- ruby-on-rails - Rails 6 所有 validate_presence_of 测试均失败
- python - 如何使用 Python 获取实时公共交通时间?
- java - 如何表示一个空的/无效的 java.nio.Path
- database - 如何在 mongoDB 中查找数组
- java - 将值从一个非静态方法传递到另一个从main?
- java - “应用程序启动方法 java.lang.reflect.InvocationTargetException 中的异常”
- c++ - 如何在其中初始化类的数组实例?