如何递归查询MongoDB文档[文件和文件夹的文件系统]

0vvn1miw  于 2022-12-29  发布在  Go
关注(0)|答案(1)|浏览(151)

bounty将在3天后过期。回答此问题可获得+150声望奖励。Nugget希望引起更多人对此问题的关注:我认为这是一个在DB中存储数据的利基用例,但它肯定是现实的。使用MongoDB或更具体地说是Typegoose,我希望收到一个答案,显示和解释如何使用上述文件系统模式对DB执行CRUD操作。

尽可能地,我希望它只在一个数据库调用中执行,因为我们的应用程序将频繁地命中数据库。请记住查询的性能和效率方面。非常感谢。
我正在开发一个应用程序,它使用MongoDB(typegoose)来存储由文件和文件夹组成的类似文件系统的(递归的)文档,但是我不知道如何查询这样的模式。
1.用户标识
1.文件夹名称的数组,按顺序排列,例如[“根”、“nestedFolder1”、“nestedFolder2”、“等...”]
1.最后选择的文件夹的ID(_ID)
该模式如下所示

import { Types } from "mongoose";
interface File {
    _id: Types.ObjectId;
    fileName: string;
    isDir: false;
    content: string;
    title: string;
    description: string;
}

interface FileSystem {
    _id: Types.ObjectId;
    folderName: string;
    isDir: true;
    files: File[] | [];
    folders: FileSystem[] | [];
}

interface Project {
    _id: Types.ObjectId;
    projectName: string;
    fileSystem: FileSystem;
}
interface User {
    _id: Types.ObjectId;
    projects: Project[];
}

更新:这里有一个副本供参考https://replit.com/@alphacoma18/mongodb-recursive-schema#server.ts

s3fp2yjn

s3fp2yjn1#

1-最简单的查询,获取所有文件系统文档:

const fileSystems = await FileSystem.find({
    // Empty Object means no condition thus give me all your data
});

2-使用$eq运算符匹配具有特定值的文档

const fileSystems = await FileSystem.find({

        isDir: true,
        folderName: { $eq: 'root' }
    });

3-使用$in运算符将特定字段与可能值的数组进行匹配。

const fileSystems = await FileSystem.find({
    isDir: true,
    folderName: { $in: ['root', 'nestedFolder1', 'nestedFolder2'] }
});

4-使用$and运算符指定多个条件

const fileSystems = await FileSystem.find({
    $and: [
        { isDir: true },
        { folderName: { $in: ['root', 'nestedFolder1', 'nestedFolder2'] } }
    ]
});

5-检索目录中的所有非空文档。

const fileSystems = await FileSystem.find({
    isDir: true,
    $or: [
        { files: { $exists: true, $ne: [] } },
        { folders: { $exists: true, $ne: [] } }
    ]
});

6-文件夹名称以字母"n"开头的所有目录

const fileSystems = await FileSystem.find({
    isDir: true,
    folderName: { $regex: '^n' }
});

现在更棘手的问题是:
1-统计文档总数

const count = await FileSystem.aggregate([
    { $count: 'total' }
]);

2-计算作为目录的文档总数

const count = await FileSystem.aggregate([
    { $match: { isDir: true } },
    { $count: 'total' }
]);

3-获取"文件夹名"和"文件名";所有文档的档案。

const fileSystems = await FileSystem.aggregate([
    { $match: { isDir: false } },
    { $project: { folderName: 1, fileName: 1 } }
]);

4-检索文件总数(isDir:false)在每个目录(isDir:正确)

const fileCounts = await FileSystem.aggregate([
    { $match: { isDir: true } },
    {
        $project: {
            folderName: 1,
            fileCount: {
                $size: {
                    $filter: {
                        input: '$files',
                        as: 'file',
                        cond: { $eq: ['$$file.isDir', false] }
                    }
                }
            }
        }
    }
]);

5-递归结构查询:FileSystem接口是递归的,因为它同时具有文件数组和文件夹数组,这两个数组的类型都是File []和FileSystem []。
要查询此递归模式,您可以在聚合管道中使用$lookup运算符,根据某些条件在FileSystem与其自身之间建立左连接。

//Retrieve All Documents from FileSystem and their child documents
const fileSystems = await FileSystem.aggregate([
    {
        $lookup: {
            from: 'FileSystem',
            localField: '_id',
            foreignField: 'parentId',
            as: 'children'
        }
    }
]);

//Use the match operator in the pipeline to filter the results: 
const fileSystems = await FileSystem.aggregate([
    {
        $lookup: {
            from: 'FileSystem',
            localField: '_id',
            foreignField: 'parentId',
            as: 'children'
        }
    },
    { $match: { isDir: true } }
]);

相关问题