为什么无法通过 _id 解析现有 MongoDB 文档,尽管将其映射到 objectId

问题描述 投票:0回答:1

我有一个现有的 MongoDB 数据库,我想将其与 Parse Server 一起使用。请注意,数据库中的数据不是由 Parse 创建的。以下是我的

theaters
集合中的文档结构示例:

{
  "_id": "59a47286cfa9a3a73e51e72c",
  "theaterId": 1000,
  "location": {
    "address": {
      "street1": "340 W Market",
      "city": "Bloomington",
      "state": "MN",
      "zipcode": "55425"
    },
    "geo": {
      "type": "Point",
      "coordinates": [-93.24565, 44.85466]
    }
  }
}

当我使用

ParseQuery
查询集合时,我得到结果,并且 Parse 似乎会自动将
_id
字段映射到
objectId
。这是我的查询和结果:

查询:

const query = new Parse.Query("theaters");
const theaters = await query.find();

结果:

[
  {
    "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"
  }
]

注意 Parse 如何将 MongoDB 中的

_id
字段映射到结果中的
objectId

但是,当我尝试使用以下代码通过

objectId
获取单个文档时:

let singleTheaterQuery = new Parse.Query("theaters");
let singleTheater = await singleTheaterQuery.get("59a47286cfa9a3a73e51e72d");

我收到以下错误:

未找到物体

到目前为止我所理解的:

  • 我的数据库中的文档不是由 Parse 创建的,因此它们缺少原生

    objectId
    字段

  • 当从
  • _id

    查询返回结果时,

    解析将 
    objectId
    映射到
    find

  • 尽管存在这种映射,Parse 似乎无法正确处理

    get
    查询。

我的问题:如果 Parse 可以在

_id
查询期间将
objectId
映射到
find
,为什么它不能使用
get
方法来处理获取单个对象?是否有配置或解决方法来启用此行为,或者这是处理现有 MongoDB 数据时 Parse 的限制?

javascript json mongodb parse-platform parse-server
1个回答
0
投票

该行为是 Parse Server 如何处理不同查询方法的结果。这就是正在发生的事情:

  • .find()
    方法执行原始 MongoDB 查询,然后转换结果,包括将
    _id
    映射到
    objectId
  • 然而,
    .get()
    方法针对 Parse 的本机数据结构进行了优化,并期望通过 Parse 创建对象(具有 Parse 格式的正确
    _id
    字段)。

您可以通过执行以下选项来解决此限制:

  • 使用带有
    _id
    字段的查询:不要使用
    .get()
    ,而是使用
    _id
    创建专门查找
    .equalTo()
    字段的查询,如上面的 getTheaterById 函数所示。
  • 使用本机 MongoDB 查询:您可以使用 Parse 的
    withJSON()
    方法编写本机 MongoDB 查询,如
    getTheaterByIdNative
    函数所示。
  • 转换您的数据:如果您计划长期将此数据库与 Parse 一起使用,您可能需要考虑迁移数据以遵循 Parse 的架构约定。

最直接的立即解决方案是使用第一种方法。以下是您将如何使用它:

const theater = await getTheaterById("59a47286cfa9a3a73e51e72d");

这应该可行,因为它查询 MongoDB 中实际的

_id
字段,而不是尝试使用 Parse 的本机对象获取机制。

下面的代码片段是 Parse Server MongoDB 查询解决方案:

// 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);
  }
}

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.