database - MongoDB:查询其字段之一等于其子文档字段之一的文档?
问题描述
给定以下具有相关书籍列表的书籍数据集:
{ "_id" : 1, "related_books" : [ { book_id: 1 }, { book_id: 2 }, { book_id: 3 } ] } <-- this one
{ "_id" : 2, "related_books" : [ { book_id: 1 } }
{ "_id" : 3, "related_books" : [ { book_id: 3 }, { book_id: 2 } ] } <-- and this one
{ "_id" : 4, "related_books" : [ { book_id: 1 }, { book_id: 2 } ] }
我试图在_id ===related_book.book_id时获取书籍列表,所以在这种情况下:
书1:它包含book_id = 1的related_book
书3:它包含book_id = 3的related_book
我一直在尝试使用聚合过滤器找到自己的方式,但无法通过检查子文档字段使其工作:
db.books.aggregate([{
"$project": {
"selected_books": {
"$filter": {
"input": "$books",
"as":"book",
"cond": { "$in": ["$_id", "$$book.related_books.book_id" ]
}}}}}])
解决方案
这是我对这个问题的解决方案:
db.getCollection("books").aggregate([{
$addFields: {
hasBookWithSameId: {
$reduce: {
input: "$related_books",
initialValue: false,
in: {$or: ["$$value", {$eq: ["$_id", "$$this.book_id"]}]}
}
}
}
},
{
$match: {
hasBookWithSameId: true
}
}])
在第一步中,我创建了一个表示布尔值的字段 hasBookWithSameId:如果存在具有相同 id 的相关书籍,则为 true,否则为 false。这是使用reduce操作符实现的,它是处理嵌入式数组的强大工具,它通过遍历数组来验证它是否有任何与父ID 相同的相关书籍。
最后,我只匹配所有将此属性设置为 true 的文档。
更新: 这个问题有一个更优雅的解决方案,只需一个聚合步骤,使用 $map 和 $anyElementTrue
db.collection.aggregate({
$match: {
$expr: {
$anyElementTrue: {
$map: {
input: "$related_books",
in: {
$eq: ["$$this.book_id", "$_id"]
}
}
}
}
}
})
推荐阅读
- javascript - 在这个例子中,如何使用 JaveScript 来模仿自定义过滤器/选择器?
- talend - tFTPConnection 从上下文设置密码不起作用
- php - 来自键名的多维数组层次结构
- python - 另一个 if 语句中带有比较运算符的 if 语句未运行
- reactjs - 如何在标签处于活动状态时更改标签的侧边框颜色
- html - 跳过链接切断整个网站的标题顶部
- jupyter-lab - jupyter-lab 中的“为输出创建新视图”不适用于全息视图
- linux - 使用 QML 调试标志点安装 PyQt5
- xml - 需要帮助 XSLT 2.0
- scala - 使用 scalapb 为地图编写 TypeMapper