Filtering date on smart field

Expected behavior

I would like to filter my data on a smart field which is type of Date. Or at least I would like my smart field to do not show me filter on date that I can’t use because they are not defined in my filter function.

Actual behavior

When I don’t define each comportment in my filter function in my smart field, I can’t filter my date. It looks like I must define each comportement for each filter defined by default.

Failure Logs

[forest] :deciduous_tree::deciduous_tree::deciduous_tree: Unexpected error: “filter” method on smart field XXX must return a condition

Context

I have a database of document type 1 linked of array of document type 2. From document type 1, I would like to see the last created document of type 2. I would also like to filter on my last created document of type 2 from type 1.

“express”: “4.17.1”,
“forest-express-mongoose”: “^7.6.0”,

can you show me your smartfield code?

{
      field: 'XXX',
      type: 'Date',
      isFilterable: true,
      get: async (document_type1) => {
        const document_type2 = await DocumentType2.find({ documentType1: document_type1._id}).sort({ createdAt: -1 });
        if (document_type2.length > 0) {
          return document_type2[0].createdAt;
        }
        return;
      },
      filter({ condition, where }) {
        switch (condition.operator) {
          default:
            return null;
        }
      },
    },

I enabled isFilterable on my smartfield so that I can filter on my date. I now have different default filter values but that doesn’t work because my filter function is empty. Should I define each comportment for each filter ? Why are there default value that I can’t use ? Is it possible to have an example off what the filter function should return for a date ? And how filtering on a date ?

Thank you!

Hello again @hugo3m

Sorry for the long delay, this was more time consuming than expected.

MongoDB is not the most convenient backend to do that, as injecting joins is not possible in the filter() and search() handlers.

I set up models similars to yours and wrote an example.

collection('films', {
  actions: [],
  fields: [
    {
      isFilterable: true,
      field: 'myDate',
      type: 'Date',

      // This gets called for each record on screen.
      // To avoid querying the database backend 15 times on list view
      // use this module: https://github.com/graphql/dataloader
      async get(film) {
        const persons = await models.persons
          .find({ preferredFilm: film._id }, ['createdAt']) // Keep only field of interest
          .sort({ createdAt: -1 })
          .limit(1); // limit to one result
        
        return persons.length ? persons[0].createdAt : null;
      },
      async filter({ where }) {
        const docs = await models.persons.aggregate([
          // Keep only docs matching user filter
          { $match: { createdAt: where }},

          // Group to keep only latest doc by documentType1 to match smart field definition
          { $group: { _id: "$preferredFilm", createdAt: { $max: "$createdAt" }}},

          // Keep only _id
          { $project: { _id: 1 }}
        ]);

        return { _id: { $in: docs.map(doc => doc._id) } };
      },
    },
  ],
  segments: [],
});