MongoDB中如何查找作为外键的ObjectId及全库任意字段中作为引用的ObjectId值
Let's break down your two MongoDB questions and fix that query issue you're facing:
1. Finding ObjectIds Used as Foreign Keys
First, let's cover the two common scenarios for how ObjectIds are stored as foreign keys:
Scenario 1: ObjectId is stored as MongoDB's native ObjectId type
If your foreign key fields use the actual ObjectId type (not a plain string), wrap the value in ObjectId() for an exact match:
// Query a single collection for docs with a top-level foreign key match db.your_collection.find({ foreign_key_field: ObjectId("6299b9f00f09ff045cc15d") }) // For nested array fields like your sample structure db.test.find({ "fourk_runs.Objectid": ObjectId("6299b9f00f09ff045cc15d") })
Scenario 2: ObjectId is stored as a string
If your data stores ObjectIds as plain strings (like the example you shared), use a direct string match without the ObjectId() wrapper:
// Match nested array elements with the string-formatted ObjectId db.test.find({ "fourk_runs.Objectid": "6299b9f00f09ff045cc15d" })
2. Searching for an ObjectId Across All Fields & Collections in a Database
Your original $text query didn't work for two key reasons:
$textsearches depend on text indexes created on specific fields — it won't scan unindexed fields automatically.- Text search uses tokenization, so short ObjectId fragments often don't get matched as expected.
Here are two reliable ways to search every field in every collection for your target ObjectId:
Option 1: Shell Script for Small Databases (Simple Approach)
Use a MongoDB Shell script to loop through all collections, then recursively check every field and array element for your target value.
For string-formatted ObjectIds:
// Replace with your target ObjectId string const targetId = "6299b9f00f09ff045cc15d"; // Get all collections in the current database const collections = db.getCollectionNames(); collections.forEach(colName => { const col = db.getCollection(colName); // Use $where to recursively scan all fields const matches = col.find({ $where: function() { function scanValue(val) { // Check if current value is the target string if (typeof val === "string" && val === targetId) return true; // Check arrays by scanning each element if (Array.isArray(val)) return val.some(item => scanValue(item)); // Check nested objects by scanning their values if (typeof val === "object" && val !== null) { return Object.values(val).some(nestedVal => scanValue(nestedVal)); } return false; } return scanValue(this); } }).toArray(); if (matches.length > 0) { print(`Found ${matches.length} matches in collection: ${colName}`); printjson(matches); } });
For native ObjectId type values:
Adjust the script to check for ObjectId instances instead of strings:
const targetId = ObjectId("6299b9f00f09ff045cc15d"); // ... (same collection loop as above) const matches = col.find({ $where: function() { function scanValue(val) { if (val instanceof ObjectId && val.equals(targetId)) return true; if (Array.isArray(val)) return val.some(item => scanValue(item)); if (typeof val === "object" && val !== null) { return Object.values(val).some(nestedVal => scanValue(nestedVal)); } return false; } return scanValue(this); } }).toArray();
Option 2: Optimized Approach for Large Databases
The $where method can be slow on big datasets. If you know common field names used for ObjectId references (like Objectid, refId, parentId), query those fields directly across collections for better performance:
const targetId = "6299b9f00f09ff045cc15d"; const collections = db.getCollectionNames(); collections.forEach(colName => { const col = db.getCollection(colName); const matches = col.find({ $or: [ { "fourk_runs.Objectid": targetId }, { "fourk_pass_fail.Objectid": targetId }, { "dr_runs.Objectid": targetId }, // Add any other known reference fields here ] }).toArray(); if (matches.length > 0) { print(`Found ${matches.length} matches in collection: ${colName}`); printjson(matches); } });
内容的提问来源于stack exchange,提问作者f.kermani




