Search does not look at Array type field contents

When I search, my search does not include array content highlights.

How do I work around this?

Expected behavior

Array is taken into consideration with search.

Actual behavior

Doesn’t search inside arrays

Failure Logs

Please include any relevant log snippets, if necessary.

Context

Please provide any relevant information about your setup.

  • Package Version: 6.3.8
  • Express Version: ~4.17.1
  • Sequelize Version: ~5.21.13
  • Database Dialect: postgres
  • Database Version: 12.2
  • Project Name: Rupie

Hi @austinrupie,

Thanks for reaching out.
Indeed, I’m afraid the default search does not include array content highlights.
Let me add this subject to our Product Board requests so that it’d be tackled in the future.

In the meantime, you could have the option to override the get route and deal with all cases… But it’d be probably quite a work.

Let me know if you have any other questions!
Thanks.

Ok. Thanks.

So I tried overriding yesterday, but I couldn’t figure it out.

// Learn what this route does here: https://docs.forestadmin.com/documentation/v/v5/reference-guide/routes/default-routes#get-a-list-of-records
  const recordsGetter = new RecordsGetter(InternalRecord);

  const params = request.query;
  const { page: { number, size }, search } = params;
  let where = {};

  if (search) {
    where = {
      [Op.or]: [
        {
          notes: {
            [Op.iLike]: `%${search}%`
          }
        },
        {
          tags: {
            [Op.contains]: [search]
          }
        },
        {
          skills: {
            [Op.contains]: [search]
          }
        }
      ]
    };
  }
  const findAll = InternalRecord.findAll({
    include: [
      {
        model: User,
        as: 'Contact'
      },
      {
        model: Job,
        as: 'Job'
      }
    ],
    offset: number - 1,
    limit: size,
    where
  });

  const count = InternalRecord.count();

  // resolve the two promises and serialize the response
  Promise.all([
    findAll, count
  ])
    .then(([
      internalRecordsFound, internalRecordsCount
    ]) => recordsGetter.serialize(internalRecordsFound, { count: internalRecordsCount }))
    .then(recordsSerialized => response.send(recordsSerialized))
    .catch(next);

  next();
});

the result-set was coming back correctly, but Forest always complained that “no records were found”.

Any advice?

Hi @austinrupie :wave: , according to the documentation you should override the two get routes.
For you:

router.get('/InternalRecord', (req, res, next) => {
  // Return here the records with your specific search logic.
  // { data: [{ internalRecord }] }
};
router.get('/InternalRecord/count', (req, res, next) => {
  // Return here the total number who match your specific search logic.
  // { count: 1 }
};

Actually, with your implementation, this second route return { count: 0 }, so the app display nothing.
Let me know if it help.

Hmm yeah, the count didn’t work. I’d love some better example around customizing this stuff if possible?

Like a single full replacement using sequelize would be very helpful.

Hi @austinrupie,

Here is an exemple of an override of the get and count routes for a similar case to yours.

I have an item model with name and tags fields. tags being an array.

// Get a list of Items
router.get('/items', permissionMiddlewareCreator.list(), (request, response, next) => {
  const recordsGetter = new RecordsGetter(items);
  const { page: { number, size }, search } = request.query;
  let where = {};

  if (search) {
    where = {
      [Op.or]: [{
        name: { [Op.iLike]: `%${search}%` }
      }, {
        tags: { [Op.contains]: [search] }
      }],
    }
  }

  items.findAll({
    where,
    offset: number - 1,
    limit: size,
  })
    .then(records => recordsGetter.serialize(records))
    .then(recordsSerialized => response.send(recordsSerialized))
    .catch(next);
});

// Get a number of Items
router.get('/items/count', permissionMiddlewareCreator.list(), (request, response, next) => {
  const { search } = request.query;
  let where = {};

  if (search) {
    where = {
      [Op.or]: [{
        name: { [Op.iLike]: `%${search}%` }
      }, {
        tags: { [Op.contains]: [search] }
      }],
    }
  }

  items.count({ where })
    .then(count => response.send({ count }))
    .catch(next);
});

It needs to be noted that this will only handle search on a perfect match for the array as sequelize does not define a contains + like operator. If you want to do so you’ll either have to craft your own SQL query or perform a custom filter in JS after retrieving the items.

I hope this will be of any help.