“迭代”通过 mongodb 中的所有文档字段
Posted
技术标签:
【中文标题】“迭代”通过 mongodb 中的所有文档字段【英文标题】:"iterate" through all document fields in mongodb 【发布时间】:2021-07-15 07:13:54 【问题描述】:我有一个包含这种形式的文档的集合:
"fields_names": ["field1", "field2", "field3"]
"field1": 1,
"field2": [1, 2, 3]
"field3": "12345"
其中 field1、field2、field3 对于每个文档都是“动态的”(我为每个文档都有“fields_names”数组中的字段名称)
我想使用聚合框架测试 2 个文档是否相等。 我使用 $lookup 阶段来获取另一个文档。 我的问题是:如何“迭代”我的收藏的整个字段?
db.collection.aggregate([
$match: "my_id": "test_id",
$lookup:
from: "collection"
let: my_id: "$my_id", prev_id: "$_id"
pipeline: [
$match: "my_id": "$$my_id", "_id": $ne: "$$prev_id"
]
as: "lookup_test"
])
在查找的管道中,我想迭代“fields_names”数组以获取字段的名称,然后访问它们的值并在“原始文档”(不是 $lookup)和其他文档($lookup 文档)。 或者:只是迭代所有字段(不包括“fields_names”数组)
我想用所有具有相同字段值的文档填充“lookup_test”数组..
【问题讨论】:
请根据您的示例文档添加您的预期结果。 【参考方案1】:您必须比较文档的两个“部分”部分,这意味着您必须(对于每个文档)在 $lookup
中执行此操作,不用说这将是一个非常昂贵的管道.话虽如此,这就是我的做法:
db.collection.aggregate([
$match:
"my_id": "test_id"
,
"$lookup":
"from": "collection",
"let":
id: "$_id",
partialRoot:
$filter:
input:
"$objectToArray": "$$ROOT"
,
as: "fieldObj",
cond:
"$setIsSubset": [
[
"$$fieldObj.k"
],
"$fields_names"
]
,
pipeline: [
$match:
$expr:
$and: [
$ne: [
"$$id",
"$_id"
]
,
$eq: [
$size: "$$partialRoot"
,
$size:
"$setIntersection": [
"$$partialRoot",
$filter:
input:
"$objectToArray": "$$ROOT"
,
as: "fieldObj",
cond:
"$setIsSubset": [
[
"$$fieldObj.k"
],
"$fields_names"
]
]
]
]
,
],
"as": "x"
])
Mongo Playground
如果您可以通过代码动态构建查询,您可以通过在$lookup
阶段使用相同的匹配查询来提高效率,如下所示:
const query = my_id: "test_id" ;
db.collection.aggregate([
$match: query
,
$lookup:
...
pipeline: [
$match: query ,
... rest of pipeline ...
]
])
这样你只匹配至少匹配初始查询的文档,这应该会大大提高查询性能(显然取决于字段 x 值熵)
另外需要注意的是,如果 x 文档匹配,您将获得 x 次相同的结果,这意味着您可能希望将 $limit: 1
阶段添加到您的管道中。
【讨论】:
以上是关于“迭代”通过 mongodb 中的所有文档字段的主要内容,如果未能解决你的问题,请参考以下文章