JKHeadley / rest-hapi

🚀 A RESTful API generator for Node.js
https://resthapi.com
MIT License
1.19k stars 153 forks source link

[Question] I'm having trouble using $text or $term #237

Open yoieh opened 4 years ago

yoieh commented 4 years ago

I'm trying to implement "free text search with autocomplete" on my front end using $text or $term while having a "custom default" query in a list pre middleware and cant get it to work as expected.

Could also be that I'm missing something.

I'm setting this in my list pre middleware

query = {
  ...query,
  isDeleted: { $ne: true },
  $where: {
    $or: [
      {
        objects: {
          _id: {
            $in: user.company.objects.map(o => o._id)
          }
        }
      },
      { createdBy: user._id },
      { company: user.company },
    ]
  }
};

When I'm using $text I have to sent a word that matches one word -1 letter to return any matching data. Example $text=Awesom will return

Awesome Frozen Sausages
Awesome Concrete Bacon
Awesome Fresh Tuna

Example $text=Aweso will return nothing. The data return matches my "default query" as $text AND "myDefault"

Next if i use $term data is returned even if I use $term=A witch is more of a result I'm after. The only problem is that it totally ignores my "default query" using it as $term OR "myDefault" This is a big problem for me do to a user aren't allowed to see data that aren't "connected" to a user...

I'm i missing something here? I have tried turning on and of config.enableTextSearch but it doesn't seem to do any difference.

yoieh commented 4 years ago

Using the $term i found importing and using the queryHelper.setTermSearch() then move $or created by setTermSearch in side of a $and with my other $or. And at last deleting the $or created by setTermSearch.

This simply moves the $or that "ignores" my $where in to an $and Dirty but it works for now..

const queryHelper = require("rest-hapi/utilities/query-helper");

...
// this function returns nothing.... but handels $term by adding a $or to query
queryHelper.setTermSearch(query, mongoose.model(modelName), Log);

query = {
  ...query,
  isDeleted: { $ne: true },

  $where: {
    $and: [
      {
        $or: [
          {
            objects: {
              _id: {
                $in: user.company.objects.map(o => o._id)
              }
            }
          },
          { company: user.company },
          { createdBy: user._id }
        ]
      }
    ]
  }
};

if (query.$or) {
  // moves the or created by setTermSearch to not ignore my `$or`
  query.$where.$and = [...query.$where.$and, { $or: query.$or }];
}

// Deleting the $or created by setTermSearch
delete query.$or;
...