在mongo db node.js中加入两个或多个查询,并使用汇总查询作为单个对象获得结果

发布于 2025-02-06 17:15:04 字数 1867 浏览 0 评论 0原文

我有两个收藏夹,如下所示:

import mongoose from "mongoose";

const projectSchema = mongoose.Schema({
  id: String,
  userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
  title: String,
  details: String,
  location: String,
  rate: String,

  status: {
    type: String,
    default: "active",
  },

  createdAt: {
    type: Date,
    default: new Date(),
  },
});

const Project = mongoose.model("Project", projectSchema);

export default Project;

import mongoose from "mongoose";

const proposalSchema = mongoose.Schema({
  id: String,
  userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
  projectId: { type: mongoose.Schema.Types.ObjectId, ref: "Project" },
  rate: String,
  message: String,

  createdAt: {
    type: Date,
    default: new Date(),
  },
});

const Proposal = mongoose.model("Proposal", proposalSchema);

export default Proposal;

为了响应GET请求,我想获得所有活动的项目,并且用户尚未将建议发送给他们,Get request将具有用户的ID。

(提案:当用户发送建议时,提案对象是在具有用户ID和ProjectID的建议集合中创建的)

我已经使用以下查询使其正常工作,但看起来并不有效和良好。有什么办法可以使用汇总查询或从中获得任何更好的方法来获得此结果?

以及我如何有效地将Objectid转换为字符串ID的方式。

export const getProjects = async (req, res) => {
  try {
    const activeProjects = await Project.find({ status: "active" }, { _id: 1 });

    const projectsWithProposals = await Proposal.find(
      {
        $and: [
          { userId: req.query.id },
          { projectId: { $in: activeProjects } },
        ],
      },
      { _id: 0, projectId: 1 }
    );

    const stringsIds = projectsWithProposals.map((id) =>
      id.projectId.toString()
    );

    const projects = await Project.find({
      $and: [{ status: "active" }, { _id: { $nin: stringsIds } }],
    });
    res.status(200).json(projects);
  } catch (error) {
    res.status(404).json({ message: error.message });
  }
};

I have two collections as follows:

import mongoose from "mongoose";

const projectSchema = mongoose.Schema({
  id: String,
  userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
  title: String,
  details: String,
  location: String,
  rate: String,

  status: {
    type: String,
    default: "active",
  },

  createdAt: {
    type: Date,
    default: new Date(),
  },
});

const Project = mongoose.model("Project", projectSchema);

export default Project;

import mongoose from "mongoose";

const proposalSchema = mongoose.Schema({
  id: String,
  userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
  projectId: { type: mongoose.Schema.Types.ObjectId, ref: "Project" },
  rate: String,
  message: String,

  createdAt: {
    type: Date,
    default: new Date(),
  },
});

const Proposal = mongoose.model("Proposal", proposalSchema);

export default Proposal;

And in response to a GET request, I want to get all the projects which are active and user has not sent the proposal to them, GET request will have the id of user.

(Proposal: When a user sends a proposal, a proposal object is created in proposals collections which has userId and ProjectId)

I have make it work using the below queries but it doesn't looks efficient and good. Is there a way I can get this result using aggregate query or any better way from this?

And also how I can efficiently can convert objectId to string Id here.

export const getProjects = async (req, res) => {
  try {
    const activeProjects = await Project.find({ status: "active" }, { _id: 1 });

    const projectsWithProposals = await Proposal.find(
      {
        $and: [
          { userId: req.query.id },
          { projectId: { $in: activeProjects } },
        ],
      },
      { _id: 0, projectId: 1 }
    );

    const stringsIds = projectsWithProposals.map((id) =>
      id.projectId.toString()
    );

    const projects = await Project.find({
      $and: [{ status: "active" }, { _id: { $nin: stringsIds } }],
    });
    res.status(200).json(projects);
  } catch (error) {
    res.status(404).json({ message: error.message });
  }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

够钟 2025-02-13 17:15:04

这是一个聚合功能,它提供了所有没有给定用户建议的项目:

function getQ (userId) {
   return [
      {
         "$match": {
            "$expr": {
               "$eq": [
                  "$status",
                  "active"
               ]
            }
         }
      },
      {
         "$lookup": {
            "from": "proposals",
            "localField": "_id",
            "foreignField": "projectId",
            "as": "proposals"
         }
      },
      {
         "$set": {
            "uids": "$proposals.userId"
         }
      },
      {
         "$unset": "proposals"
      },
      {
         "$match": {
            "$expr": {
               "$not": [
                  {
                     "$in": [
                        mongoose.Types.ObjectId(userId),
                        "$uids"
                     ]
                  }
               ]
            }
         }
      },
      {
         "$unset": "uids"
      },
      {
         "$limit": 10
      }
   ]
}

db.Project.aggregate(getQ("62a61df204f2ce244ce0ffcc")) // input is user._id
  .then(console.log)
  .catch(console.error)

我已经使用了标准的杂种_ids,因此您可能必须在需要时调整代码。

查询确实仅输出项目收集数据,尽管还可以很容易地包含其他数据。

当心limit在此处是常数。您也可以将skiplimit转换为函数参数,如果您要使用大量结果,则可以使功能更加灵活。

Here is a aggregation function which delivers all Projects which have no proposal from a given user:

function getQ (userId) {
   return [
      {
         "$match": {
            "$expr": {
               "$eq": [
                  "$status",
                  "active"
               ]
            }
         }
      },
      {
         "$lookup": {
            "from": "proposals",
            "localField": "_id",
            "foreignField": "projectId",
            "as": "proposals"
         }
      },
      {
         "$set": {
            "uids": "$proposals.userId"
         }
      },
      {
         "$unset": "proposals"
      },
      {
         "$match": {
            "$expr": {
               "$not": [
                  {
                     "$in": [
                        mongoose.Types.ObjectId(userId),
                        "$uids"
                     ]
                  }
               ]
            }
         }
      },
      {
         "$unset": "uids"
      },
      {
         "$limit": 10
      }
   ]
}

db.Project.aggregate(getQ("62a61df204f2ce244ce0ffcc")) // input is user._id
  .then(console.log)
  .catch(console.error)

I have used the standard mongoose _ids so you might have to adapt the code if required.

The query does only output the Project collection data, although it would be easy to include other data as well.

Beware that limit is constant here. You could also convert skip and limit to function paramters which would make the function much more flexible if you are working with huge amounts of results.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文