question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dynamic Aggregation stages using string template

See original GitHub issue

Related with the issue 102 I wanted to add facet aggregation.

This time I used string templates. ( if it is possible to add facet to the answer in issue 102, it would also help, but anyway I chose string templates this time).

I could dynamically constructed the string template like this, and it worked, but it is dirty:) Do you think this kind of solution is good? Any suggestions?

If the pipeline method would accept input of an array (array of stages), this kind of dynamic (optional) aggregations would be easier? Would you consider adding this feature?

        [HttpGet("search-facet")]
        public async Task<IActionResult> SearchAndFacet(FilterProductDTO dto)
        {

            int page = dto.Page.HasValue ? dto.Page.Value : 1;
            int pageSize = dto.PageSize.HasValue ? dto.PageSize.Value : 10;
            int skip = (page - 1) * pageSize;

            var stages = new List<string>();

            if (!string.IsNullOrEmpty(dto.SearchTerm))
            {
                stages.Add(@"{$match: {
	                      $text: { $search: '<search_term>' }
	                    }}".Replace("<search_term>", dto.SearchTerm));

                stages.Add(@" {$sort: {
	                      score: { $meta: 'textScore' }
	                    }}");
            }

            if (!string.IsNullOrEmpty(dto.CategoryId))
            {
                stages.Add(@" {
                '$match': {
                  'Category': new ObjectId('<category_id>')
                }
              }".Replace("<category_id>", dto.CategoryId));
            }

            if (dto.MinPrice.HasValue)
            {
                stages.Add(@" {
                '$match': {
                  'Price': { $gte: <min_price> }
                }
              }".Replace("<min_price>", dto.MinPrice.Value.ToString(new NumberFormatInfo() { NumberDecimalSeparator = "."})));
            }

            if (dto.MaxPrice.HasValue)
            {
                stages.Add(@" {
                '$match': {
                  'Price': { $lte: <max_price> }
                }
              }".Replace("<max_price>", dto.MaxPrice.Value.ToString(new NumberFormatInfo() { NumberDecimalSeparator = "." })));
            }

            stages.Add(@"{$facet: {
		                      TotalRecords: [
			                    {
			                      $count: 'total'
			                    }
		                      ],
		                      Products: [
			                    {
			                      $skip: <skip>
			                    },
			                    {
			                      $limit: <limit>
			                    }
		                      ]
	                    }}"); //.Replace("<skip>", skip.ToString()).Replace("<limit>", pageSize.ToString()));

            stages.Add(@"{$addFields: {
	                      TotalRecords: {
		                    $arrayElemAt: [ '$TotalRecords.total', 0]
	                      }
	                    }}");

            var template = $"[{string.Join(',', stages)}]";

            var pipeline = new Template<ProductEntity, ProductSearchResultDTO>(template)
                    .Tag("skip", skip.ToString())
                    .Tag("limit", pageSize.ToString());

            var products = await DB.PipelineAsync(pipeline);

            return Ok(products);

        }

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
susahin80commented, Apr 13, 2021

Great, I wil try

0reactions
susahin80commented, Apr 13, 2021

ok thanks, AppendStage method is good enough 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best way to form an aggregate dynamic mongo query ...
I will form the query dynamically to get the result, so there are two options: either I can create a query in my...
Read more >
Dynamic MongoDB Aggregations - Roger Kitain
We've seen how to specify MongoDB aggregations for querying document contents using an aggregation that queries for specific array elements. Now ...
Read more >
String templates
Examples · Aggregation pipeline · Aggregation pipeline with different result type · Find with match expression · Update with aggregation pipeline · Update...
Read more >
A MongoDB Aggregation Example with $match, $group & $ ...
Follow along this MongoDB aggregation example that uses $match, $group and $sort to query Chicago housing data, sample dataset included.
Read more >
Build a NodeJS MongoDB Aggregation Pipeline in 3 Easy ...
This post lists the different MongoDB Aggregation Stages and the steps to set up NodeJS MongoDB Aggregation Pipeline using MongoDB Atlas ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found