最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

我怎么弄清楚为什么MongoDB NodeJS驱动程序没有为单个集合返回有效查询的结果?

IT培训 admin 3浏览 0评论

我怎么弄清楚为什么MongoDB NodeJS驱动程序没有为单个集合返回有效查询的结果?

我正在将MongoDB v3.2.7用于NodeJS v10.16.0。我创建了一个MongoRepository基类,在生产环境中使用了几年。有时在开发中,我发现古怪的行为,它不会为特定集合返回任何结果。我曾经以为这是因为我没有在两次查询之间关闭客户端。我现在不太确定。

我正在通过Express服务器运行代码,并且有六个其他调用也可以正常工作。然后我得到这个查询和投影,但没有结果(即使这些结果在命令行和Robo 3T中也可以):

查询={“ pin”:“ xxxxxx”,“ documentId”:“ 5c584a76a690bb28ff8021cb”,“ page”:1},投影= {“ _class”:0,“ documentId”:0,“ pin”:0,“ base64”:0} data = []

我不知道如何开始调试它。帮助?

这是基类代码:

import { MongoClient, ObjectId } from 'mongodb';
import 'dotenv/config';

const url = process.env...; // elided to hide our secrets
const dbname = process.env...; // elided to hide our secrets

class MongoRepository
{
    /**
     * Returns the database using the configuration
     */
    async getDatabase()
    {
        if (!MongoRepository.client)
        {
            MongoRepository.client = new MongoClient(url, { useNewUrlParser: true });

            await MongoRepository.client.connect();

            if (!MongoRepository.client || !MongoRepository.client.db(dbname))
            {
                throw new Error(`Unable to connect to Mongo with URL '${url}'`);
            }
        }

        return MongoRepository.client.db(dbname);
    }

    /**
     * Override this method in children to add any special query filter for a collection.
     * @param {*} query query object to modify
     */
    addRepositoryFilter(query) {
        return query;
    }

    /**
     * Generic find method that takes a query and a projection.
     *
     * @param {*} query Lookup parameters
     * @param {*} projection Fields to return or not return from the search
     *
     */
    async find(query, projection = {})
    {
        query = this.addRepositoryFilter(query);

        let db = await this.getDatabase();

        return await db.collection(this.CollectionName).find(query).project(projection).toArray();
    }
}

export default MongoRepository;

这里是没有得到结果的子类:

import MongoRepository from "./MongoRepository";

class ViewerPageRepository extends MongoRepository
{
    get CollectionName()
    {
        return 'viewerPage';
    }

    async findByPinDocumentIdPage(pin, documentId, page, projection)
    {
        documentId = this.objectIdToString(documentId);

        let query = {
            pin: pin,
            documentId: documentId,
            page: page
        };

        console.log(`Query = ${JSON.stringify(query)}, Projection = ${JSON.stringify(projection)}`);

        return await this.find(query, projection);
    }
}

export default ViewerPageRepository;
回答如下:

在考虑检查查询中documentId的类型后,我想到了这一点。它以十六进制字符串形式存储在我正在查询的集合中。我没有在代码中包含objectIdToString函数,但是如果它是valueOf实例,它将在documentId上调用ObjectId。这应该已经将其转换为字符串,但是由于某种原因,我又找回了另一个ObjectId实例(也许是我调用过valueOf的同一实例-我没有检查)。因此,这似乎是由于MongoDB驱动程序的ObjectId::valueOf方法中的错误引起的。我将报告此问题。

我怎么弄清楚为什么MongoDB NodeJS驱动程序没有为单个集合返回有效查询的结果?

我正在将MongoDB v3.2.7用于NodeJS v10.16.0。我创建了一个MongoRepository基类,在生产环境中使用了几年。有时在开发中,我发现古怪的行为,它不会为特定集合返回任何结果。我曾经以为这是因为我没有在两次查询之间关闭客户端。我现在不太确定。

我正在通过Express服务器运行代码,并且有六个其他调用也可以正常工作。然后我得到这个查询和投影,但没有结果(即使这些结果在命令行和Robo 3T中也可以):

查询={“ pin”:“ xxxxxx”,“ documentId”:“ 5c584a76a690bb28ff8021cb”,“ page”:1},投影= {“ _class”:0,“ documentId”:0,“ pin”:0,“ base64”:0} data = []

我不知道如何开始调试它。帮助?

这是基类代码:

import { MongoClient, ObjectId } from 'mongodb';
import 'dotenv/config';

const url = process.env...; // elided to hide our secrets
const dbname = process.env...; // elided to hide our secrets

class MongoRepository
{
    /**
     * Returns the database using the configuration
     */
    async getDatabase()
    {
        if (!MongoRepository.client)
        {
            MongoRepository.client = new MongoClient(url, { useNewUrlParser: true });

            await MongoRepository.client.connect();

            if (!MongoRepository.client || !MongoRepository.client.db(dbname))
            {
                throw new Error(`Unable to connect to Mongo with URL '${url}'`);
            }
        }

        return MongoRepository.client.db(dbname);
    }

    /**
     * Override this method in children to add any special query filter for a collection.
     * @param {*} query query object to modify
     */
    addRepositoryFilter(query) {
        return query;
    }

    /**
     * Generic find method that takes a query and a projection.
     *
     * @param {*} query Lookup parameters
     * @param {*} projection Fields to return or not return from the search
     *
     */
    async find(query, projection = {})
    {
        query = this.addRepositoryFilter(query);

        let db = await this.getDatabase();

        return await db.collection(this.CollectionName).find(query).project(projection).toArray();
    }
}

export default MongoRepository;

这里是没有得到结果的子类:

import MongoRepository from "./MongoRepository";

class ViewerPageRepository extends MongoRepository
{
    get CollectionName()
    {
        return 'viewerPage';
    }

    async findByPinDocumentIdPage(pin, documentId, page, projection)
    {
        documentId = this.objectIdToString(documentId);

        let query = {
            pin: pin,
            documentId: documentId,
            page: page
        };

        console.log(`Query = ${JSON.stringify(query)}, Projection = ${JSON.stringify(projection)}`);

        return await this.find(query, projection);
    }
}

export default ViewerPageRepository;
回答如下:

在考虑检查查询中documentId的类型后,我想到了这一点。它以十六进制字符串形式存储在我正在查询的集合中。我没有在代码中包含objectIdToString函数,但是如果它是valueOf实例,它将在documentId上调用ObjectId。这应该已经将其转换为字符串,但是由于某种原因,我又找回了另一个ObjectId实例(也许是我调用过valueOf的同一实例-我没有检查)。因此,这似乎是由于MongoDB驱动程序的ObjectId::valueOf方法中的错误引起的。我将报告此问题。

发布评论

评论列表 (0)

  1. 暂无评论