MongoDB complex query design
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I have a tricky mongoDB problem that I have never encountered. My internet research was unsuccessful.

The Documents:

The documents in my collection have a search object containing named keys and array values. The keys are named after one of eight categorys and the corresponding value is an array containing items from that category.

The Query

The query has the format of an object containing the same category - keys and array - values.

I created a gist.
Link: https://gist.github.com/FinnFrotscher/491eb8c7777724f33bc34254e9c65c59

The desired outcome
- If the query is empty, I want all documents.
- If the query has one category and any number of items, I want all the documents that have all of the items in the specified category.
- If the query has more then one category, I want all the documents that have all of the items in all of the specified categorys.

-If a category is not defined in the query, it sould be neglected for search.

My Tries

I tried all kinds of variations of:

XX.find({
'search': {
  "$elemMatch": {
    'tool': {
      "$in" : ['feedback']
    }
  }
}

Also tried: 'search.test': {$all: (query.test ? query.test : [])} which gives me no results if I have nothing selected; the right documents when I am only looking inside the test category; and nothing when I additionally look inside the usage category.

Where are these queries coming from and what do they represent? They seem needlessly complex.
slang 3 years ago
They are generated from a URL query.
FinnFrotscher 3 years ago
let tools = [] const search = {} for (var q in query) { if (query.hasOwnProperty(q)) { if (query[q]) { search['search.'+q] = {$all: query[q] } } } search['legit'] = true } if (Object.keys(query).length > 0) { tools = ToolsCollection.find(search).fetch() } else { tools = ToolsCollection.find({'legit':true}).fetch() } solved it
FinnFrotscher 3 years ago
awarded to dr-dimitru

Crowdsource coding tasks.

1 Solution

Winning solution

let tools = [];
const search = {};
for (var q in query) { 
  if (query.hasOwnProperty(q)) { 
    if (query[q]) { 
      search['search.'+q] = {
        $all: query[q] 
      }
    }
 } 

  search['legit'] = true ;
} 

if (Object.keys(query).length > 0) {
   tools = ToolsCollection.find(search).fetch() 
} else { 
   tools = ToolsCollection.find({'legit':true}).fetch() 
}