簡體   English   中英

Mongoose 查詢在 find() 中有效但在聚合匹配中無效

[英]Mongoose query works in find() but not in aggregation match

MongoDb 查詢在countDocuments中運行良好,但在aggregation $match中運行不正常,下面是代碼

  let query = [];
  let sort = { createdAt: 1 };

  const page = req.body.page || 1;
  const limit = req.body.limit || 10;
  let skip = (page - 1) * limit

  if (!_.isEmpty(req.body.search)) {
    query.push({
      "name": {
        $regex: req.body.search, $options: "i",
      }
    })
  }

  if (!_.isUndefined(req.body.featured)) {
    query.push({ "featured": req.body.featured });
  }
  if (!_.isUndefined(req.body.todays_deal)) {
    query.push({ "todays_deal": req.body.todays_deal });
  }


 if (req.body.subcategory_id && Array.isArray(req.body.subcategory_id)) {
    query.push({ "subCategory_id": { "$in": req.body.subcategory_id } })
  }

  if (!_.isEmpty(req.body.brand_id) && _.isArray(req.body.brand_id)) {
    query.push({ "brand_id": { "$in": req.body.brand_id } });
  }

  if (!_.isEmpty(req.body.size) && _.isArray(req.body.size)) {
    query.push({ "variants.size": { "$in": req.body.size } });
  }

  if (!_.isEmpty(req.body.color) && _.isArray(req.body.color)) {
    query.push({ "variants.color": { "$in": req.body.color } });
  }

  if (!_.isEmpty(req.body.tags) && _.isArray(req.body.tags)) {
    query.push({ "tags": { "$in": req.body.tags } });
  }

  if (req.body.price) {
    query.push({
      "price": {
        $gte: req.body.price.minimum, $lte: req.body.price.maximum
      }
    })
  }

  if (!_.isEmpty(req.body.sort_by)) {
    switch (req.body.sort_by) {
      case "newest":
        sort = { createdAt: -1 };
        break;
      case "oldest":
        sort = { createdAt: 1 };
        break;
      case "price_low_to_high":
        sort = { "variants.price": 1 };
        break;
      case "price_high_to_low":
        sort = { "variants.price": -1 };
        break;
      default:
        return res.status(404).json({ msg: "Invalid sort value" });
    }
  }

  try {
    const productCount = await Product.countDocuments({ $and: query });
    let allProducts = await Product.aggregate([
      { "$match": { $and: query } },
      { "$sort": {  _id: -1 } },
      {
        $project: {
          modal_name: 0,
          manufactured_by: 0,
          manufacturing_country: 0,
          stock_visible: 0,
          cash_on_delivery: 0,
          featured: 0,
          todays_deal: 0,
          publish: 0,
          created_by: 0,
          created_by_id: 0,
          unit: 0,
          variants_image: 0,
          minimum_purchase_quantity: 0
        }
      },
      { $facet: { product: [{$skip: skip},{ $limit: limit }]}},
      { $unwind: "$product" }
    ])

    // .find({ $and: query }).select({
    //   modal_name: 0,
    //   manufactured_by: 0,
    //   manufacturing_country: 0,
    //   stock_visible: 0,
    //   cash_on_delivery: 0,
    //   featured: 0,
    //   todays_deal: 0,
    //   publish: 0,
    //   created_by: 0,
    //   created_by_id: 0,
    //   unit: 0,
    //   variants_image: 0,
    //   minimum_purchase_quantity: 0
    // }).populate({
    //   path: 'category_id',
    //   model: 'Category',
    //   select: { '_id': 1, 'name': 1 }
    // })
    //   .skip(skip)
    //   .limit(limit)
    //   .sort(sort)
    //   .select("-__v")
    //   .lean();

    /* .aggregate([
    { "$match": { $or: query } },
    { "$sort": sort },
    {
      $project: 
    },
    { $facet: { product: [{ $skip: skip }, { $limit: limit }] } },
    { $unwind: '$product' }
  ]) */

    let result = response.OK
    result.data = {
      products: allProducts,
      info: {
        totalNumber: productCount,
        hasNextPage: limit * page < productCount,
        hasPreviousPage: page > 1,
        nextPage: page + 1,
        previousPage: page - 1,
        lastPage: Math.ceil(productCount / limit),
      },
    }

    return res.status(200).send(successRes(result, res.statusCode));
  } catch (error) {
    console.log("Server Error in product.getProducts", error);
    return res.status(500).send(errorsRes(response.SERVER_ERROR, res.statusCode));
  }

計數返回 40 個項目,而聚合返回 null 下面的數組是查詢可以有多個對象。

[
  {
    "$or": [
      {
        "category_id": {
          "$in": [
            "6214fea736df45237c39ca65"
          ]
        }
      },
      {
        "subCategory_id": {
          "$in": [
            "6214fea736df45237c39ca65"
          ]
        }
      }
    ]
  },
{ "brand_id": { "$in": ["6214fea736df45237c78979"] } }
]

上面的查詢也適用於find()查詢

   .find({ $and: query })
    .select({
      modal_name: 0,
      manufactured_by: 0,
      manufacturing_country: 0,
      stock_visible: 0,
      cash_on_delivery: 0,
      featured: 0,
      todays_deal: 0,
      publish: 0,
      created_by: 0,
      created_by_id: 0,
      unit: 0,
      variants_image: 0,
      minimum_purchase_quantity: 0
    })
      .skip(skip)
      .limit(limit)
      .sort(sort)
      .select("-__v")
      .lean();

更新

{
   "_id":{
      "$oid":"62170046b58fab4938818a6f"
   },
   "brand_id":{
      "$oid":"6214feb936df45237c39cac1"
   },
   "tags":[
      "Nen?XfucBd",
      "M|b}vy`FY9",
      "vd>J^a[^mm",
      "34370",
      "X<\"QoWs##B",
      "}v6GsaDE\"e",
      "g^Q`:r\\/(}",
      "45884",
      "IYCN&LkI&,",
      "81259"
   ],
   "image":[
      "https://images.unsplash.com/photo-1493552152660-f915ab47ae9d?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0ODAz&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
      "https://images.unsplash.com/photo-1493552152660-f915ab47ae9d?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0ODEw&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
      "https://images.unsplash.com/photo-1432251407527-504a6b4174a2?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLG1lbnNmYXNoaW9ufHx8fHx8MTY0NTI4NDg4Mw&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920"
   ],
   "colors":[
      "#1b444e",
      "#134a77",
      "#1b6030"
   ],
   "variants_image":[
      {
         "color":"#1b444e",
         "img":[
            "https://images.unsplash.com/photo-1592265911347-2d381a17e161?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzYx&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1566955244976-483f8d7965e2?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzY2&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1590736945722-bf5c39bc6513?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzU1&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920"
         ]
      },
      {
         "color":"#134a77",
         "img":[
            "https://images.unsplash.com/photo-1592265911347-2d381a17e161?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzYx&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1566955244976-483f8d7965e2?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzY2&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1457968867385-9f877f3f2bce?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0NzY0&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920"
         ]
      },
      {
         "color":"#1b6030",
         "img":[
            "https://images.unsplash.com/photo-1483959651481-dc75b89291f1?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLG1lbnNmYXNoaW9ufHx8fHx8MTY0NTI4NDg5MA&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1493552152660-f915ab47ae9d?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0ODEw&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920",
            "https://images.unsplash.com/photo-1498335746477-0c73d7353a07?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=1080&ixid=MnwxfDB8MXxyYW5kb218MHx8d2FsbHBhcGVyLGZhc2hpb258fHx8fHwxNjQ1Mjg0Nzg0&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=1920"
         ]
      }
   ],
   "stock_visible":false,
   "cash_on_delivery":false,
   "featured":false,
   "todays_deal":false,
   "publish":false,
   "item_code":"403dbdf8-e2af-43ee-941d-0cac51347741",
   "name":"Awesome Rubber Computer",
   "slug":"intelligent-steel-pizza",
   "description":"Qui sapiente omnis illo delectus dolor libero. Ex temporibus quod omnis. Quas voluptates omnis culpa cum laboriosam alias dolor nesciunt id. Vel animi dolores eius autem deleniti quod enim nesciunt. Sed voluptatem suscipit consectetur quas. Voluptatem sint ipsam nulla iure dolores facilis id. Nihil occaecati natus ex nobis esse autem ullam. Ut velit dolorum id itaque consequatur ut beatae ut similique. Aperiam iusto qui et illo. Quisquam molestiae ad alias laudantium modi tempore commodi. Rem aut ut. Nihil voluptatem tenetur beatae consectetur. Consectetur odio numquam aut. Dicta mollitia nesciunt corrupti magni et. Dolores rerum quam ad ea numquam repudiandae aut ut. Aut accusamus explicabo et vel. Est quos adipisci dolor aliquam. Sapiente fuga dolor.",
   "modal_name":"Handmade Frozen Table",
   "manufactured_by":"Davis - Hegmann",
   "manufacturing_country":"Bermuda",
   "category_id":{
      "$oid":"6214fec536df45237c39cafe"
   },
   "subCategory_id":{
      "$oid":"6214fec636df45237c39cb00"
   },
   "unit":"8",
   "price":842,
   "stock":53,
   "discount":14,
   "special_price":724.12,
   "minimum_purchase_quantity":1,
   "product_video_url":"https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4",
   "variants":[
      {
         "_id":{
            "$oid":"62170046b58fab4938818a70"
         },
         "sku":"abe17cd2-642f-4267-b9fd-b6c34c31d799",
         "size":"s",
         "color":"#1b444e",
         "price":542,
         "discount":"29",
         "special_price":"384.82",
         "quantity":50
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a71"
         },
         "sku":"137cf6c5-df2f-4e22-ab9e-e2dec15b3630",
         "size":"m",
         "color":"#1b444e",
         "price":675,
         "discount":"22",
         "special_price":"526.50",
         "quantity":19
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a72"
         },
         "sku":"03179397-60a2-414b-acd4-af3916e374c1",
         "size":"l",
         "color":"#1b444e",
         "price":933,
         "discount":"20",
         "special_price":"746.40",
         "quantity":22
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a73"
         },
         "sku":"0f7c5e92-8aed-4308-92c7-e24ba4d8fd17",
         "size":"s",
         "color":"#134a77",
         "price":299,
         "discount":"12",
         "special_price":"263.12",
         "quantity":3
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a74"
         },
         "sku":"c824490c-f943-414a-91b1-15554fd21bd1",
         "size":"m",
         "color":"#134a77",
         "price":820,
         "discount":"23",
         "special_price":"631.40",
         "quantity":63
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a75"
         },
         "sku":"f487a863-13a8-43e7-b710-525db504af6a",
         "size":"l",
         "color":"#134a77",
         "price":265,
         "discount":"22",
         "special_price":"206.70",
         "quantity":49
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a76"
         },
         "sku":"d8c4d17b-626c-4440-951a-6bbceb8aae67",
         "size":"s",
         "color":"#1b6030",
         "price":953,
         "discount":"28",
         "special_price":"686.16",
         "quantity":28
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a77"
         },
         "sku":"a1780a1b-dc86-4391-83a6-20d5fa3a5bbb",
         "size":"m",
         "color":"#1b6030",
         "price":326,
         "discount":"27",
         "special_price":"237.98",
         "quantity":5
      },
      {
         "_id":{
            "$oid":"62170046b58fab4938818a78"
         },
         "sku":"318669fd-0637-46c7-8af4-b0ab3bbb6ca1",
         "size":"l",
         "color":"#1b6030",
         "price":519,
         "discount":"17",
         "special_price":"430.77",
         "quantity":55
      }
   ],
   "created_by":"Admin",
   "created_by_id":{
      "$oid":"62121e477f0690117d79b86d"
   },
   "createdAt":{
      "$date":"2022-02-24T03:49:26.410Z"
   },
   "updatedAt":{
      "$date":"2022-02-24T03:49:26.410Z"
   },
   "__v":0
}```

感謝您提供示例文檔。

我做了一些假設並使用了您的確切$match條件(查詢)

  • $skip : 第一次查詢應該為 0,只有當頁面大小超過時,skip 值才會大於 0,以便進一步提取。 如果第一次提取的值大於 0,這可能是問題的原因。
  • $limit :現在我指定為 10
  • $sort :這可能是任何一個,它不會是問題的原因。 現在,我已經用 _id desc 排序了

聚合返回多個文檔,每個文檔都有產品字段,因為我們使用$facet

MongoDB 游樂場: https://mongoplayground.net/p/LguFlH541QJ

讓我知道是否有幫助。 如果問題依舊,可以提供MongoDB Playground鏈接或者更多文檔讓我看看。

更新

我在countDocumentsaggregate之間看到的唯一區別是$skip & $limit部分。 如果req.body.page未定義或為 1,它應該可以正常工作。

您也可以在不使用$facet的情況下調整aggregate 修改后的聚合查詢如下。

db.product.aggregate([
    { "$match": { $and: query } },
    { "$sort": { _id: -1 } },
    {
        $project: {
            modal_name: 0,
            manufactured_by: 0,
            manufacturing_country: 0,
            stock_visible: 0,
            cash_on_delivery: 0,
            featured: 0,
            todays_deal: 0,
            publish: 0,
            created_by: 0,
            created_by_id: 0,
            unit: 0,
            variants_image: 0,
            minimum_purchase_quantity: 0,
        }
    },
    //       { $facet: { product: [{ $skip: skip }, { $limit: limit }] } },
    //       { $unwind: '$product' }
    {
        $skip: skip
    },
    {
        $limit: limit
    },
    {
        $project: {
            _id: 0,
            product: '$$ROOT'
        }
    }
])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM