Why can’t Parse fetch existing MongoDB documents by _id despite mapping it to objectId

I have an existing MongoDB database that I want to use with Parse Server. Please note that the data in the database was not created by Parse. Here’s an example of the structure of a document in my theaters collection:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"_id": "59a47286cfa9a3a73e51e72c",
"theaterId": 1000,
"location": {
"address": {
"street1": "340 W Market",
"city": "Bloomington",
"state": "MN",
"zipcode": "55425"
},
"geo": {
"type": "Point",
"coordinates": [-93.24565, 44.85466]
}
}
}
</code>
<code>{ "_id": "59a47286cfa9a3a73e51e72c", "theaterId": 1000, "location": { "address": { "street1": "340 W Market", "city": "Bloomington", "state": "MN", "zipcode": "55425" }, "geo": { "type": "Point", "coordinates": [-93.24565, 44.85466] } } } </code>
{
  "_id": "59a47286cfa9a3a73e51e72c",
  "theaterId": 1000,
  "location": {
    "address": {
      "street1": "340 W Market",
      "city": "Bloomington",
      "state": "MN",
      "zipcode": "55425"
    },
    "geo": {
      "type": "Point",
      "coordinates": [-93.24565, 44.85466]
    }
  }
}

When I query the collection using ParseQuery, I get results, and Parse seems to automatically map the _id field to an objectId. Here’s my query and the result:

Query:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const query = new Parse.Query("theaters");
const theaters = await query.find();
</code>
<code>const query = new Parse.Query("theaters"); const theaters = await query.find(); </code>
const query = new Parse.Query("theaters");
const theaters = await query.find();

Result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>[
{
"theaterId": 1000,
"location": {
"address": {
"street1": "340 W Market",
"city": "Bloomington",
"state": "MN",
"zipcode": "55425"
},
"geo": {
"type": "Point",
"coordinates": [-93.24565, 44.85466]
}
},
"objectId": "59a47286cfa9a3a73e51e72c"
},
{
"theaterId": 1003,
"location": {
"address": {
"street1": "45235 Worth Ave.",
"city": "California",
"state": "MD",
"zipcode": "20619"
},
"geo": {
"type": "Point",
"coordinates": [-76.512016, 38.29697]
}
},
"objectId": "59a47286cfa9a3a73e51e72d"
}
]
</code>
<code>[ { "theaterId": 1000, "location": { "address": { "street1": "340 W Market", "city": "Bloomington", "state": "MN", "zipcode": "55425" }, "geo": { "type": "Point", "coordinates": [-93.24565, 44.85466] } }, "objectId": "59a47286cfa9a3a73e51e72c" }, { "theaterId": 1003, "location": { "address": { "street1": "45235 Worth Ave.", "city": "California", "state": "MD", "zipcode": "20619" }, "geo": { "type": "Point", "coordinates": [-76.512016, 38.29697] } }, "objectId": "59a47286cfa9a3a73e51e72d" } ] </code>
[
  {
    "theaterId": 1000,
    "location": {
      "address": {
        "street1": "340 W Market",
        "city": "Bloomington",
        "state": "MN",
        "zipcode": "55425"
      },
      "geo": {
        "type": "Point",
        "coordinates": [-93.24565, 44.85466]
      }
    },
    "objectId": "59a47286cfa9a3a73e51e72c"
  },
  {
    "theaterId": 1003,
    "location": {
      "address": {
        "street1": "45235 Worth Ave.",
        "city": "California",
        "state": "MD",
        "zipcode": "20619"
      },
      "geo": {
        "type": "Point",
        "coordinates": [-76.512016, 38.29697]
      }
    },
    "objectId": "59a47286cfa9a3a73e51e72d"
  }
]

Notice how Parse maps the _id field from MongoDB to objectId in the results.

However, when I try to fetch a single document by its objectId using the following code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>let singleTheaterQuery = new Parse.Query("theaters");
let singleTheater = await singleTheaterQuery.get("59a47286cfa9a3a73e51e72d");
</code>
<code>let singleTheaterQuery = new Parse.Query("theaters"); let singleTheater = await singleTheaterQuery.get("59a47286cfa9a3a73e51e72d"); </code>
let singleTheaterQuery = new Parse.Query("theaters");
let singleTheater = await singleTheaterQuery.get("59a47286cfa9a3a73e51e72d");

I get the following error:

No object found

What I understand so far:

  • The documents in my database were not created by Parse, so they lack the native objectId field

  • Parse maps _id to objectId when returning results from a find query.

  • Despite this mapping, Parse doesn’t seem to handle get queries properly.

My question: If Parse can map _id to objectId during a find query, why can’t it handle fetching a single object using the get method? Is there a configuration or workaround to enable this behavior, or is this a limitation of Parse when working with existing MongoDB data?

The behaviour is a result of how Parse Server handles different query methods. This is what’s happening:

  • The .find() method performs a raw MongoDB query and then transforms the results, including mapping _id to objectId.
  • The .get() method, however, is optimized for Parse’s native data structure and expects the object to have been created through Parse (with a proper _id field in Parse’s format).

You can work around this limitation by doing the following options:

  • Use Query with _id Field: Instead of using .get(), create a query that specifically looks for the _id field using .equalTo() as shown in the getTheaterById function above.
  • Use Native MongoDB Query: You can use Parse’s withJSON() method to write native MongoDB queries as demonstrated in the getTheaterByIdNative function.
  • Transform Your Data: If you’re planning to use this database long-term with Parse, you might want to consider migrating your data to follow Parse’s schema conventions.

The most straightforward immediate solution is to use the first approach. Here’s how you would use it:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const theater = await getTheaterById("59a47286cfa9a3a73e51e72d");
</code>
<code>const theater = await getTheaterById("59a47286cfa9a3a73e51e72d"); </code>
const theater = await getTheaterById("59a47286cfa9a3a73e51e72d");

This should work because it queries the actual _id field in MongoDB rather than trying to use Parse’s native object fetching mechanism.

The code snippets below are Parse Server MongoDB Query Solutions:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Utility function to query by MongoDB _id
async function getTheaterById(theaterId) {
const query = new Parse.Query("theaters");
// Add a constraint to match the _id field
query.equalTo('_id', theaterId);
try {
const results = await query.first();
return results;
} catch (error) {
console.error('Error fetching theater:', error);
throw error;
}
}
// Alternative approach using MongoDB native query
async function getTheaterByIdNative(theaterId) {
const query = new Parse.Query("theaters");
// Use MongoDB's native query format
query.withJSON({
'_id': theaterId
});
try {
const results = await query.first();
return results;
} catch (error) {
console.error('Error fetching theater:', error);
throw error;
}
}
// Helper function to convert string ID to MongoDB ObjectId
function convertToObjectId(idString) {
const mongodb = require('mongodb');
try {
return new mongodb.ObjectId(idString);
} catch (error) {
console.error('Invalid ObjectId format:', error);
throw error;
}
}
// Example usage with both approaches
async function demonstrateQueries() {
try {
// Using the direct _id query
const theater1 = await getTheaterById("59a47286cfa9a3a73e51e72d");
console.log('Result using _id query:', theater1);
// Using native MongoDB query
const theater2 = await getTheaterByIdNative("59a47286cfa9a3a73e51e72d");
console.log('Result using native query:', theater2);
// If you need to convert string to ObjectId first
const objectId = convertToObjectId("59a47286cfa9a3a73e51e72d");
const theater3 = await getTheaterById(objectId);
console.log('Result using converted ObjectId:', theater3);
} catch (error) {
console.error('Error in demonstration:', error);
}
}</code>
<code>// Utility function to query by MongoDB _id async function getTheaterById(theaterId) { const query = new Parse.Query("theaters"); // Add a constraint to match the _id field query.equalTo('_id', theaterId); try { const results = await query.first(); return results; } catch (error) { console.error('Error fetching theater:', error); throw error; } } // Alternative approach using MongoDB native query async function getTheaterByIdNative(theaterId) { const query = new Parse.Query("theaters"); // Use MongoDB's native query format query.withJSON({ '_id': theaterId }); try { const results = await query.first(); return results; } catch (error) { console.error('Error fetching theater:', error); throw error; } } // Helper function to convert string ID to MongoDB ObjectId function convertToObjectId(idString) { const mongodb = require('mongodb'); try { return new mongodb.ObjectId(idString); } catch (error) { console.error('Invalid ObjectId format:', error); throw error; } } // Example usage with both approaches async function demonstrateQueries() { try { // Using the direct _id query const theater1 = await getTheaterById("59a47286cfa9a3a73e51e72d"); console.log('Result using _id query:', theater1); // Using native MongoDB query const theater2 = await getTheaterByIdNative("59a47286cfa9a3a73e51e72d"); console.log('Result using native query:', theater2); // If you need to convert string to ObjectId first const objectId = convertToObjectId("59a47286cfa9a3a73e51e72d"); const theater3 = await getTheaterById(objectId); console.log('Result using converted ObjectId:', theater3); } catch (error) { console.error('Error in demonstration:', error); } }</code>
// Utility function to query by MongoDB _id
async function getTheaterById(theaterId) {
  const query = new Parse.Query("theaters");
  // Add a constraint to match the _id field
  query.equalTo('_id', theaterId);
  try {
    const results = await query.first();
    return results;
  } catch (error) {
    console.error('Error fetching theater:', error);
    throw error;
  }
}

// Alternative approach using MongoDB native query
async function getTheaterByIdNative(theaterId) {
  const query = new Parse.Query("theaters");
  // Use MongoDB's native query format
  query.withJSON({
    '_id': theaterId
  });
  try {
    const results = await query.first();
    return results;
  } catch (error) {
    console.error('Error fetching theater:', error);
    throw error;
  }
}

// Helper function to convert string ID to MongoDB ObjectId
function convertToObjectId(idString) {
  const mongodb = require('mongodb');
  try {
    return new mongodb.ObjectId(idString);
  } catch (error) {
    console.error('Invalid ObjectId format:', error);
    throw error;
  }
}

// Example usage with both approaches
async function demonstrateQueries() {
  try {
    // Using the direct _id query
    const theater1 = await getTheaterById("59a47286cfa9a3a73e51e72d");
    console.log('Result using _id query:', theater1);

    // Using native MongoDB query
    const theater2 = await getTheaterByIdNative("59a47286cfa9a3a73e51e72d");
    console.log('Result using native query:', theater2);
    
    // If you need to convert string to ObjectId first
    const objectId = convertToObjectId("59a47286cfa9a3a73e51e72d");
    const theater3 = await getTheaterById(objectId);
    console.log('Result using converted ObjectId:', theater3);
    
  } catch (error) {
    console.error('Error in demonstration:', error);
  }
}

Hope this helps.

EDIT:

I’ve made some changes in the previous code samples:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> // Correct way to query by MongoDB ObjectId
async function getTheaterById(theaterId) {
const query = new Parse.Query("theaters");
// Use matches query constraint with regex pattern for MongoDB ObjectId
query.matches('_id', '^' + theaterId + '$');
try {
const result = await query.first();
if (!result) {
throw new Error('Theater not found');
}
return result;
} catch (error) {
console.error('Error fetching theater:', error);
throw error;
}
}
// Example usage
async function fetchTheater() {
try {
const theaterId = "573a1392f29313caabcd9aab";
const theater = await getTheaterById(theaterId);
console.log('Found theater:', theater.toJSON());
} catch (error) {
console.error('Error:', error);
}
}
// Alternative approach using containedIn if you have multiple IDs
async function getTheatersByMultipleIds(theaterIds) {
const query = new Parse.Query("theaters");
// Use containedIn for multiple IDs
query.containedIn('_id', theaterIds);
try {
const results = await query.find();
return results;
} catch (error) {
console.error('Error fetching theaters:', error);
throw error;
}
}
// Example usage for multiple IDs
async function fetchMultipleTheaters() {
try {
const theaterIds = [
"573a1392f29313caabcd9aab",
"573a1392f29313caabcd9aac"
];
const theaters = await getTheatersByMultipleIds(theaterIds);
console.log('Found theaters:', theaters.map(t => t.toJSON()));
} catch (error) {
console.error('Error:', error);
}
}
</code>
<code> // Correct way to query by MongoDB ObjectId async function getTheaterById(theaterId) { const query = new Parse.Query("theaters"); // Use matches query constraint with regex pattern for MongoDB ObjectId query.matches('_id', '^' + theaterId + '$'); try { const result = await query.first(); if (!result) { throw new Error('Theater not found'); } return result; } catch (error) { console.error('Error fetching theater:', error); throw error; } } // Example usage async function fetchTheater() { try { const theaterId = "573a1392f29313caabcd9aab"; const theater = await getTheaterById(theaterId); console.log('Found theater:', theater.toJSON()); } catch (error) { console.error('Error:', error); } } // Alternative approach using containedIn if you have multiple IDs async function getTheatersByMultipleIds(theaterIds) { const query = new Parse.Query("theaters"); // Use containedIn for multiple IDs query.containedIn('_id', theaterIds); try { const results = await query.find(); return results; } catch (error) { console.error('Error fetching theaters:', error); throw error; } } // Example usage for multiple IDs async function fetchMultipleTheaters() { try { const theaterIds = [ "573a1392f29313caabcd9aab", "573a1392f29313caabcd9aac" ]; const theaters = await getTheatersByMultipleIds(theaterIds); console.log('Found theaters:', theaters.map(t => t.toJSON())); } catch (error) { console.error('Error:', error); } } </code>
    // Correct way to query by MongoDB ObjectId
async function getTheaterById(theaterId) {
  const query = new Parse.Query("theaters");
  // Use matches query constraint with regex pattern for MongoDB ObjectId
  query.matches('_id', '^' + theaterId + '$');
  
  try {
    const result = await query.first();
    if (!result) {
      throw new Error('Theater not found');
    }
    return result;
  } catch (error) {
    console.error('Error fetching theater:', error);
    throw error;
  }
}

// Example usage
async function fetchTheater() {
  try {
    const theaterId = "573a1392f29313caabcd9aab";
    const theater = await getTheaterById(theaterId);
    console.log('Found theater:', theater.toJSON());
  } catch (error) {
    console.error('Error:', error);
  }
}

// Alternative approach using containedIn if you have multiple IDs
async function getTheatersByMultipleIds(theaterIds) {
  const query = new Parse.Query("theaters");
  // Use containedIn for multiple IDs
  query.containedIn('_id', theaterIds);
  
  try {
    const results = await query.find();
    return results;
  } catch (error) {
    console.error('Error fetching theaters:', error);
    throw error;
  }
}

// Example usage for multiple IDs
async function fetchMultipleTheaters() {
  try {
    const theaterIds = [
      "573a1392f29313caabcd9aab",
      "573a1392f29313caabcd9aac"
    ];
    const theaters = await getTheatersByMultipleIds(theaterIds);
    console.log('Found theaters:', theaters.map(t => t.toJSON()));
  } catch (error) {
    console.error('Error:', error);
  }
}

Key changes here are:

  • The use of matches() with a regex pattern to match the exact ObjectId string instead of using withJSON() or direct equalTo()

  • The pattern '^' + theaterId + '$' will ensure an exact match of the ID (the ^ matches the start of the string and $ matches the end)

You can use it like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const query = new Parse.Query("theaters");
const theaterId = "573a1392f29313caabcd9aab";
query.matches('_id', '^' + theaterId + '$');
try {
const theater = await query.first();
console.log(theater);
} catch (error) {
console.error("Error while fetching theater by ID:", error);
}
</code>
<code>const query = new Parse.Query("theaters"); const theaterId = "573a1392f29313caabcd9aab"; query.matches('_id', '^' + theaterId + '$'); try { const theater = await query.first(); console.log(theater); } catch (error) { console.error("Error while fetching theater by ID:", error); } </code>
const query = new Parse.Query("theaters");
const theaterId = "573a1392f29313caabcd9aab";
query.matches('_id', '^' + theaterId + '$');

try {
  const theater = await query.first();
  console.log(theater);
} catch (error) {
  console.error("Error while fetching theater by ID:", error);
}

If you want to query multiple theaters by their IDs, use the containedIn approach as shown in the getTheatersByMultipleIds function in the modified code samples above.

This should work with your existing MongoDB data structure without requiring any modifications to the database.

Try this and see if it fixes the problem.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật