Node.js Mongoose:如果对象数组中的数组中存在值,则过滤数据

Node.js Mongoose:如果对象数组中的数组中存在值,则过滤数据,node.js,mongodb,mongoose,aggregation-framework,mongoose-schema,Node.js,Mongodb,Mongoose,Aggregation Framework,Mongoose Schema,我有一个使用Aggregate的mongoose查询,根据对象数组中的值过滤数据,由于需求的变化,我遇到了麻烦 这是我的数据在MongoDB中的样子(它已被虚拟数据填充) 目标:根据用户提供的类别(假设其“SD-WAN”)过滤服务,之前该类别是单一的,现在它是一个值数组,因为一个服务可以属于多个类别 以前的解决方案 我用于单数类别值的mongoose查询如下: db.Collection("suppliers").aggregate([ { $project: {

我有一个使用Aggregate的mongoose查询,根据对象数组中的值过滤数据,由于需求的变化,我遇到了麻烦

这是我的数据在MongoDB中的样子(它已被虚拟数据填充)

目标:根据用户提供的类别(假设其“SD-WAN”)过滤服务,之前该类别是单一的,现在它是一个值数组,因为一个服务可以属于多个类别

以前的解决方案 我用于单数类别值的mongoose查询如下:

db.Collection("suppliers").aggregate([
  {
    $project: {
      services: {
        $filter: {
          input: "$services",
          as: "services",
          cond: { $eq: ["$$services.category", "SD-WAN" ] },
        },
      },
    },
  },
  { $match: { services: { $exists: true, $not: { $size: 0 } } } },
]);
$$services.categories
中搜索
SD-WAN
时遇到问题,这是一个值数组。是否有任何方法可以更新上述查询,以便使用
$eq
管道操作符或其他解决方案在
services.categories
数组中搜索值

预期结果

"_id" : ObjectId("5ef44528af5a1a2a641cd52b"),
"services" : [ 
    {
        "active" : true,
        "_id" : ObjectId("5ef44528af5a1a2a641cd52d"),
        "name" : "Company Management",
        "title" : "Company Helpline",
        "description" : "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
        "categories" : [ 
            "SD-WAN", 
            "Security and Compliance"
        ],
        "sub_categories" : [ 
            "Solution"
        ],
    }
]

如果有人能在这方面帮助我,我将不胜感激。如果需要更多信息,请询问。谢谢。

这是您要找的

[
  {
    $unwind: "$services"
  },
  {
    $match: {
      "services.categories": "SD-WAN"
    }
  },
  {
    $group: {
      _id: "$_id",
      active: {
        $first: "$active"
      },
      name: {
        $first: "$name"
      },
      contacts: {
        $first: "$contacts"
      },
      services: {
        $addToSet: "$services"
      }
    }
  }
]
  • 使用
    $unwind
    展平阵列
  • 使用
    $match
    进行筛选
  • 使用
    $group
    将其重新分组
  • 我们只提供服务。这就是我使用
    $addToSet


    工作

    这里是你想要的

    [
      {
        $unwind: "$services"
      },
      {
        $match: {
          "services.categories": "SD-WAN"
        }
      },
      {
        $group: {
          _id: "$_id",
          active: {
            $first: "$active"
          },
          name: {
            $first: "$name"
          },
          contacts: {
            $first: "$contacts"
          },
          services: {
            $addToSet: "$services"
          }
        }
      }
    ]
    
  • 使用
    $unwind
    展平阵列
  • 使用
    $match
    进行筛选
  • 使用
    $group
    将其重新分组
  • 我们只提供服务。这就是我使用
    $addToSet


    工作

    这里是另一种不使用聚合的方法 游乐场连接:

    输出:

    [
      {
        "_id": ObjectId("5ef44528af5a1a2a641cd52b"),
        "services": [
          {
            "_id": ObjectId("5ef44528af5a1a2a641cd52d"),
            "active": true,
            "categories": [
              "SD-WAN",
              "Security and Compliance"
            ],
            "description": "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
            "name": "Company Management",
            "sub_categories": [
              "Solution"
            ],
            "title": "Company Helpline"
          }
        ]
      }
    ]
    

    这里是另一种不使用聚合的方法 游乐场连接:

    输出:

    [
      {
        "_id": ObjectId("5ef44528af5a1a2a641cd52b"),
        "services": [
          {
            "_id": ObjectId("5ef44528af5a1a2a641cd52d"),
            "active": true,
            "categories": [
              "SD-WAN",
              "Security and Compliance"
            ],
            "description": "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
            "name": "Company Management",
            "sub_categories": [
              "Solution"
            ],
            "title": "Company Helpline"
          }
        ]
      }
    ]
    

    感谢您的快速响应,这完美地解决了我的问题!$first做什么?当我们放松时,可能会有与数组大小相同的重复项(“服务”)。所以当我们分组时,我们只需要第一个对象,因为其他对象都是重复的谢谢您的快速响应,这完美地解决了我的问题!$first做什么?当我们放松时,可能会有与数组大小相同的重复项(“服务”)。因此,当我们对它进行分组时,我们只需要第一个对象,因为其他对象都是重复的。此查询在一定程度上起作用,因为它只返回它在类别
    SD-WAN
    中找到的第一个服务,同一类别可以有多个服务。查询应筛选具有该类别的服务。使用find有什么方法可以做到这一点吗?此查询部分起作用,因为它只会返回它找到的第一个服务的类别
    SD-WAN
    ,同一类别可以有多个服务。查询应筛选具有该类别的服务。使用find有什么方法可以做到这一点吗?