1

I am currently building a cart system on my mongodb ecommerce app. I need help on how to query and compare array.

here document of cart:

{
    "_id" : ObjectId("5d0531e27c8fa1029017ea20"),
    "user" : ObjectId("5d0371319315c715fc34b0b0"),
    "active" : true,
    "item" : [ 
        {
            "product" : ObjectId("5d013eb63a2bdd11a46c8dd3"),
            "option" : [ 
                {
                    "name" : "Ukuran",
                    "value" : "Biru"
                }
            ],
            "quantity" : 1
        }, 
        {
            "product" : ObjectId("5d013eb63a2bdd11a46c8dd3"),
            "option" : [ 
                {
                    "name" : "Ukuran",
                    "value" : "Biru"
                }
            ],
            "quantity" : 1
        }
    ],
    "created_at" : ISODate("2019-06-15T17:58:58.762Z"),
    "updated_at" : ISODate("2019-06-15T17:59:13.334Z"),
    "__v" : 0
}

I want to compare object of item.option field, so my cart system is if cart on database have same object option i will add quantity, otherwise push new object to item.

so current I am not asking on how to implement my cart system, but I want to compare each item.option object

I've already tried this

const cart = await CartModel.find({
    "item.option": option
})

and get error Error: Query filter must be an object, got an array

2 Answers 2

2

Solved by myself, after many experiment finally i combine $in and $elemMatch for compare each array of object

// this is will dynamic
const optionArray = [
   {
      "name": "Warna",
      "value": "Biru"
   },
   {
      "name": "Ukuran",
      "value": "XL"
   }
]

const compareOptionQuery = []

for (let i = 0; i < optionArray.length; i++) {
   compareOptionQuery.push({
      $elemMatch: {
         ...option[i]
      }
   })
}

const cart = await CartModel.aggregate([
  {
     $and: [
        {
           _id: cartId,
           user: userId
        },
        {
          'item.option': {
            $in: [...compareOptionQuery]
          }
        }
     ]
  }
])
Sign up to request clarification or add additional context in comments.

Comments

0

The issue with your implementation is that in CartModel.find("item.option": option) your filter (first parameter) encounters an array instead of an object.

This is because you are trying to call for an object option from item, however option is as element of an array field item.

If you wish to access item from an array field, you must specify conditions on the elements in the array field item using {<array field>: {<operator1>: <value1>}} like so:

CartModel.find({
   item: {$option: option}
})

3 Comments

because is my problem, the option object are dynamic i cannot specify field manual
Regardless of array length/dynamicness, the above implementation should find you the element with the corresponding option. What are you unable to do?
Thanks for your answer, i solve myself problem after trying trying and trying. Look at this pastebin.com/HnhW5YW8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.