Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use with Aggregation? #91

Open
shubham-powerplay opened this issue May 28, 2021 · 1 comment
Open

How to use with Aggregation? #91

shubham-powerplay opened this issue May 28, 2021 · 1 comment

Comments

@shubham-powerplay
Copy link

Do you want to request a feature, an issue, or report a bug?
A feature

What is the current behaviour?
Doesn't work with aggregate

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?

  • should work with aggregation pipeline with pagination (skip & limit)

If this is a feature request, what is the motivation or use case for changing
the behaviour?

  • Let say I am using an aggregation pipeline for a query and want to filter data based on search

Please mention other relevant information such as Node.js and mongoose version.

@AlbinBackstrom
Copy link

AlbinBackstrom commented Sep 12, 2021

I'am also looking for this. Would be a great feature! I managed to get it working with the aggregate framwork by adding functionality for this is my local node_modules. This of course will be overwritten when you update or do anything else with the installed packaged. So if you use it it will probably needs to be forked or in some other way saved. Also this is not really tested in a good way, I only tried it to fit my specific needs and my data. And to be fair i just copy pasted the original code so i probably missed something. So my strong advice is don't use this in production, but maybe you can tweak it so it will work as you need it. I also didn't try the pagination but the function takes a regular pipeline so it should probably work as normal i guess.

If someone has the knowledge and time, it would be very appreciated if that person took a look and developed this code more and tested (or rewrote it completley) and make a PR to this repo.

Add this function to node_modules/mongoose-fuzzy-searching/index.js


function fuzzyAggregate(...args){
  const queryArgs = Object.values(args);
  let pipeline = queryArgs[0] // this is the passed in pipeline
  const { exact, queryString } = getArgs(queryArgs[1]);
 
 if (!queryString) {
    return this.find();
  }

  const { checkPrefixOnly, defaultNgamMinSize } = getDefaultValues(queryArgs[1]);

  const query = exact
    ? `"${queryString}"`
    : nGrams(queryString, false, defaultNgamMinSize, checkPrefixOnly).join(' ');
  
  const match =  { $match: { $text: { $search: query } } };
  pipeline.unshift(match); // the match stage with $text $search needs to be first stage to run in the pipeline

  const addFields = {
         $addFields : { confidenceScore: { $meta: 'textScore' } }
  };

  pipeline.push(addFields)

  const sort = {
         $sort : { confidenceScore: { $meta: 'textScore' } }
  }
  pipeline.push(sort)
  return this.aggregate(pipeline)
}

Put this in the bottom of node_modules/mongoose-fuzzy-searching/index.js in the module.exports function

schema.statics.fuzzyAggregate = function (...args) {
    return fuzzyAggregate.apply(this, args);
  };

  schema.query.fuzzyAggregate = function (...args) {
    return fuzzyAggregate.apply(this, args);
  };

Usage:

 const result = await MyModel.fuzzyAggregate(
    [ // First argument, a whole pipeline.
      { $match: { isPublished: false } },
      {
        $lookup: {
          from: 'users',
          localField: 'vetted.user',
          foreignField: '_id',
          as: 'string',
        },
      },
    ],
    'search string' // this is the secong argument and the text we want to search
  );

console.log(result);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants