kRiZ
kRiZ

Reputation: 815

In Mongoose, query fields based on array

I am trying to query documents from a mongodb collection, based on array of input query parameters sent from URL.

Sample Database Data

[
    {
        "drawings": {
            "circle": [],
            "square": [
                {
                    "id": "828",
                    "name": "square"
                }
            ],
            "cube": []
    },
    {
        "drawings": {
            "circle": [
                {
                    "id": "827",
                    "name": "circle"
                }
            ],
            "square": [],
            "cube": []
    },
    {
        "drawings": {
            "circle": [],
            "square": [],
            "cube": [
                {
                    "id": "829",
                    "name": "cube"
                }
            ]
    }
]   

Input Query Parameter:

query = ["square","cube"];

Expected Output:

[
    {
        "drawings": {
            "circle": [],
            "square": [
                {
                    "id": "828",
                    "name": "square"
                }
            ],
            "cube": []
    },
    {
        "drawings": {
            "circle": [],
            "square": [],
            "cube": [
                {
                    "id": "829",
                    "name": "cube"
                }
            ]
    }
]

Best suited Mongoose Query:

Schema.find({
    $or:[
        {'drawings.square':{$elemMatch:{ name:'square'}}},
        {'drawings.cube':{$elemMatch:{ name:'cube'}}}
    ]
});

Tried Below method. But, it is not correct.

let draw = ["square","cube"];
let draw_query =[];
for (let a=0; a<draw.length;a++){
    draw_query.push("{\"drawings."+ draw[a] +"\':{$elemMatch:{ name:\"" + draw[a] + "\"}}}");
}

It creates array with single quoted strings. It cannot be used.

[ '{"drawings.square":{$elemMatch:{ name:"square"}}}',
  '{"drawings.cube":{$elemMatch:{ name:"cube"}}}' ]

How to generate this mongoose query dynamically? or is there any better mongoose query to achieve the expected result.

Upvotes: 1

Views: 194

Answers (1)

mickl
mickl

Reputation: 49945

You can query it directly using dot notation so the query should look like below:

db.collection.find({
  $or: [
    {
      "drawings.square.name": "square"
    },
    {
      "drawings.circle.name": "circle"
    }
  ]
})

You can build it in JS using .map(), try:

var query = ["square","cube"];
var orQuery = { $or: query.map(x => ({ [x + ".name"]: x }) ) }

Upvotes: 1

Related Questions