简体   繁体   中英

Nodejs, Mongodb filter sub array of array of objects

Hi everyone I have an array of objects with some populated fields. This is the schema of the product.

import mongoose, { Schema } from 'mongoose';

const productSchema = new mongoose.Schema(
  {
    name: String,
    description: String,
    sku: String,
    barcode: String,
    isActive: Boolean,
    quantity: Number,
    availability: String,
    taxClass: [{ type: Schema.Types.ObjectId, ref: 'TaxClass' }],
    images: [{ type: Schema.Types.ObjectId, ref: 'Image' }],
    variants: [{ type: Schema.Types.ObjectId, ref: 'Variant' }],
    tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }],
    price: {
      comparePrice: Number,
      price: Number
    },
    seo: {
      name: String,
      keywords: [
        {
          name: String
        }
      ],
      description: String,
      image: String
    }
  },
  { timestamps: true }
);

const Product = mongoose.model('Product', productSchema);
export default Product;

So i have a function and I want to return all the products with the variant color of green.

export const returnFilteredProducts = async (_, { filters = null, page = 1, limit = 20 }, context) => {
  await jwtAuthentication.verifyTokenMiddleware(context);

  try {
    let searchQuery = {};

    const products = await Product.find(searchQuery).populate(['variants', 'tags', 'images', 'taxClass']);

    console.log(products.filter((item) => item.variants.filter((e) => e.color.indexOf('green') >= 0)));

    return {
      products
    };
  } catch (error) {
    handleError(error);
  }
};

The thing is that it does not return me the document with a variant color of green, instead it returns all the documents.

I am implementing a filtering system so I don't filter the products with in the frontend with redux.

Regarding the filtering method that is applied into the products array:

products.filter((item) => item.variants.filter((e) => e.color.indexOf('green') >= 0))

Inner call item.variants.filter() returns an array.

The outer call: products.filter() will include the product item, since the array will coerce into true, even when empty.

You can use method Array.some() for the inner call, which will return a boolean true if at least one item (e) in item.variants has the desired color.

This way you will filter-out all the product items that do-not contain the desired color in at least one element of the item.variants array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM