How to dynamically add conditions or filters to aggregate query

Hi, I would like to add or remove conditions or filters based on the input to the function. For ex, if a subcategory array is passed to the function (other words, not empty), then I want to add it to the query. In the below example, it may be a condition added after the color filer. Read the Q’s on stack overflow and other places, but unable to find a solution. Thanks for your help

Here is the query:

user_collection = pymongo.collection.Collection(g.db, self.get_search_collection())
result = user_collection.aggregate([{"$search": {"index": self.get_index(),
	 "compound": {"must": [{"text": {
		 "query": [inputs["occasion_names"]],
		 "path": "occasion"}},
			   {"compound": {"filter": [
				   { 'text': { 'query': ['black'], 'path': 'color' } },
				   {"range": {
					   "gte": inputs["age_floor"],
					   "path": "age_lo"}},
				   {"range": {
					   "gte": inputs["age_ceiling"],
					   "path": "age_hi"}},
				   {'range': {'path': 'created_dt',
							  'gt': myDatetime}}
			   ]}}
		   ]}}},
	{"$sort": {"age_lo": -1, "created_dt": -1, "price": sort_order}}])

Appreciate the help

An aggregation pipeline is simply an array of JSON documents. Nothing stops you from building it dynamically with ifs and whiles. What is interesting in your example is that it looks like you already do some thing close to that with you variable inputs.

You could take M220P from MongoDB University or at least download the course material. It’s full of dynamic queries.

Interesting… I am not sure if I am doing variable inputs. I am still learning. May be my question is not clear. Anyways, I appreciate you looking into this. I will look for help elsewhere and will download the material from the course if available.

What?

What is?

That is a variable named inputs and you are accessing dynamically some of its attributes. You also have the variables myDatetime and sort_order.

No it is clear. I really recommend that you take the course.

Appreciate your customer obsession. I have already taken a few lessons. I haven’t seen content touching my problem,. I will continue to listen. However, I want to try explaining the problem again. I understand that I am using variables, but the goal is to dynamically alter the query based on the inputs to the function. For ex, if “age_floor” is not sent, I want the following to be removed from the query.

				   {"range": {
					   "gte": inputs["age_floor"],
					   "path": "age_lo"}},

Thank you

I do not want to leave the wrong impression. It is not customer obsession since I am not employed by MongoDB. I am just a independent contrator that really really likes MongoDB, Atlas, Compass, Charts, …

I am not a python programmer (I really really do not like the fact that code indentation implies code blocks) but I will try to demonstrate how it is done.

Like I mentioned

# Initialize compound_filter with the static part of the query
# So compound_filter is an array (I think they call it a list in python)
# of object (I think they call it Dictionary in python)

compound_filter = [  { 'text': { 'query': ['black'], 'path': 'color' } } ]

#  Dynamically add age_floor to compound_filter if age_floor is sent

if ( not inputs["age_floor"] is None ) :
    compound_filter.append( {"range": {
					   "gte": inputs["age_floor"],
					   "path": "age_lo"}} )

# Dynamically add age_ceiling to compound_filter if age_ceiling is sent

if ( not inputs["age_ceiling"] is None ) :
    compound_filter.append( {"range": {
					   "gte": inputs["age_ceiling"],
					   "path": "age_hi"}} )

# Then complete compound_filter with semi static date part

compound_filter.append( {'range': {'path': 'created_dt',
							  'gt': myDatetime}} )

result = user_collection.aggregate([{"$search": {"index": self.get_index(),
	 "compound": {"must": [{"text": {
		 "query": [inputs["occasion_names"]],
		 "path": "occasion"}},
			   {"compound": {"filter": compound_filter}}
		   ]}}},
	{"$sort": {"age_lo": -1, "created_dt": -1, "price": sort_order}}])

Like I wrote, I am not a python programmer so use at your own risk since it is untested code. But since it is the most basic use of list, dictionary and if it should be good.

@Saravana_Srinivasan, I provided a potential solution more than a week ago.

If you

I will appreciate that you mark my post as the solution so that others know that it works.

If it does not, please share the issues you encountered.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.