Mongodb - 如何找到文档共享"partially"一组预定义的字段?

Mongodb - How to find documents sharing "partially" a set of fields predefined?

我正在尝试在 MongoDB CLI 中编写一个查询,以从一组特定的、预定的字段中搜索共享任意数量字段的文档。

举个例子:让我们考虑一个由具有可变字段的文档组成的数据库。这些字段可以在文档之间共享,但不一定。

{
   _id: ObjectId("AAA"),
   field1: "value_a",
   field2: "value_b",
   field3: "value_l",
   field6: "value_n"
}
{
   _id: ObjectId("BBB"),
   field1: "value_c",
   field3: "value_e"
}
{
   _id: ObjectId("CCC"),
   field2: "value_f",
   field4: "value_g"
}
{
   _id: ObjectId("DDD"),
   field1: "value_m",
   field5: "value_h",
   field2: "value_i",
   field6: "value_j",
   field7: "value_k"
}
{
   _id: ObjectId("EEE"),
   field8: "value_o"
}

挑战是要有一个查询,其中不仅可以指定感兴趣的字段,还可以specify/force文档之间共享的字段数量(而不是完全匹配,如下所述使用 $exists)。对于文档可能有但不在列表中的字段,它们是否存在无关紧要。

为了清楚起见,假设我们对上面显示的文档中的字段列表 ["field1"、"field3"、"field6"、"field8"] 感兴趣,并且我们想知道哪些文档共享 X个字段(不管是哪一个,只要是我们定义的列表中的即可)。

让我们调用 QUERY1 查询返回文档共享 exactly X 字段,如下所述:

此外,让我们调用 QUERY2 查询返回至少共享 X 个字段的文档?

我一直在尝试使用 $exists,但问题是查询 returns 文档正好共享这四个字段,没有上面解释的灵活性:db.documents.find({'field1' : {$exists: true}, 'field3' : {$exists: true}, 'field6' : {$exists: true}, 'field8' : {$exists: true})

有人知道 QUERY1 和 QUERY2 怎么写吗?

此外,由于我想从这些查询的结果中创建新的集合,理想情况下,查询最后会使用以下函数:.forEach(function(x){db.newCollection.insert(x)});

非常感谢您的帮助,非常感谢。

db.documents.aggregate([
    {
        "$project": {
            "matchedFieldCount": {
                $size: {
                    "$filter": {
                        "input": {
                            "$objectToArray": "$$ROOT"
                        },
                        "cond": {
                            "$in": [
                                "$$this.k",
                                [
                                    "field1",
                                    "field3",
                                    "field6",
                                    "field8"
                                ]
                            ]
                        }
                    }
                }
            }
        }
    },
    { $match: { matchedFieldCount: 1 } }
])

您可以调整管道中的 $match 以执行 QUERY1 或 QUERY2。如果您愿意,可以通过再添加一个流水线步骤来仅投射 _id。