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 字段,如下所述:
- 仅包含一个字段的文档:returns 带有 ObjectId("EEE") 的文档
- 正好有两个字段的文档:returns ObjectId("BBB") 和 ("DDD") 的文档
- 恰好包含三个字段的文档:returns 带有 ObjectId("AAA") 的文档
此外,让我们调用 QUERY2 查询返回至少共享 X 个字段的文档?
- 包含至少一个字段的文档:returns 包含 ObjectId("AAA")、("BBB")、("DDD")、("EEE") 的文档
- 包含至少两个字段的文档:returns 包含 ObjectId("AAA")、("BBB")、("DDD") 的文档
- 包含至少三个字段的文档:returns 带有 ObjectId("AAA") 的文档
我一直在尝试使用 $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。
我正在尝试在 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 字段,如下所述:
- 仅包含一个字段的文档:returns 带有 ObjectId("EEE") 的文档
- 正好有两个字段的文档:returns ObjectId("BBB") 和 ("DDD") 的文档
- 恰好包含三个字段的文档:returns 带有 ObjectId("AAA") 的文档
此外,让我们调用 QUERY2 查询返回至少共享 X 个字段的文档?
- 包含至少一个字段的文档:returns 包含 ObjectId("AAA")、("BBB")、("DDD")、("EEE") 的文档
- 包含至少两个字段的文档:returns 包含 ObjectId("AAA")、("BBB")、("DDD") 的文档
- 包含至少三个字段的文档:returns 带有 ObjectId("AAA") 的文档
我一直在尝试使用 $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。