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

[-] Smart Field Search - Ease the search on smart fields and deprecate old ways to do it #372

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

VincentMolinie
Copy link
Member

@VincentMolinie VincentMolinie commented Feb 3, 2020

Pull Request checklist:

  • Write an explicit title for the Pull Request
  • Write changes made in the CHANGELOG.md
  • Create automatic tests
  • Test manually the implemented changes
  • Review my own code (indentation, syntax, style, simplicity, readability)
  • Wonder if you can improve the existing code

Before

We had to do this kind of thing

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      var searchCondition = {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };

      query.where[Op.and][0][Op.or].push(searchCondition);

      return query;
    }
  }]
});

After

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      return {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };
    }
  }]
});

Copy link
Member

@SteveBunlon SteveBunlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this planed to be exported to the mongoose liana ?
Also I don't see any related clickup / trello card.
Has this been discussed with the product team ?
Is Marc aware he'll need to update the documentation ?
I let you investigate the test failures.

Comment on lines +29 to +34
async function getWhere() {
if (!where) {
where = await searchBuilder.perform(params.associationName);
}
return where;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[IMPROVEMENT] I don't like that, the where value should initialized as the other, no need to create a function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's async. So I cannot initialized it like the other 😢

include,
}],
})
.then((record) => ((record && record[params.associationName]) || []));
}

function getCount() {
async function getCount() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SCARED] You are returning a promise of promise (wait for the count value and return it directly instead of returning a promise of the value) and you don't wait for the 'getWhere()' promise value here again. The where operator expects an object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A promise of a promise is a promise 🤔

@arnaudbesnier
Copy link
Contributor

Pull Request checklist:

  • Write an explicit title for the Pull Request
  • Write changes made in the CHANGELOG.md
  • Create automatic tests
  • Test manually the implemented changes
  • Review my own code (indentation, syntax, style, simplicity, readability)
  • Wonder if you can improve the existing code

Before

We had to do this kind of thing

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      var searchCondition = {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };

      query.where[Op.and][0][Op.or].push(searchCondition);

      return query;
    }
  }]
});

After

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      return {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };
    }
  }]
});

So you can't use include to join if necessary?

@VincentMolinie
Copy link
Member Author

Pull Request checklist:

  • Write an explicit title for the Pull Request
  • Write changes made in the CHANGELOG.md
  • Create automatic tests
  • Test manually the implemented changes
  • Review my own code (indentation, syntax, style, simplicity, readability)
  • Wonder if you can improve the existing code

Before

We had to do this kind of thing

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      var searchCondition = {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };

      query.where[Op.and][0][Op.or].push(searchCondition);

      return query;
    }
  }]
});

After

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      return {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };
    }
  }]
});

So you can't use include to join if necessary?

You are absolutely right. I thought about it, but most of the time includes does not work as expected (For example try with a hasMany...).

I think we need to rework a little bit the smart field to add a requirement property for example
That field could look like requirement: ['users.*', 'companies.{id,name}']...

Tell me what you think about it @arnaudbesnier

@arnaudbesnier
Copy link
Contributor

Pull Request checklist:

  • Write an explicit title for the Pull Request
  • Write changes made in the CHANGELOG.md
  • Create automatic tests
  • Test manually the implemented changes
  • Review my own code (indentation, syntax, style, simplicity, readability)
  • Wonder if you can improve the existing code

Before

We had to do this kind of thing

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      var searchCondition = {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };

      query.where[Op.and][0][Op.or].push(searchCondition);

      return query;
    }
  }]
});

After

collection('customers', {
  fields: [{
    field: 'fullname',
    type: 'String',
    get: (customer) => {
      return customer.firstname + ' ' + customer.lastname;
    },
    search: function (query, search) {
      let s = models.sequelize;
      let split = search.split(' ');

      return {
        [Op.and]: [
          { firstname: { [Op.like]: `%${split[0]}%` } },
          { lastname: { [Op.like]: `%${split[1]}%` } },
        ]
      };
    }
  }]
});

So you can't use include to join if necessary?

You are absolutely right. I thought about it, but most of the time includes does not work as expected (For example try with a hasMany...).

I think we need to rework a little bit the smart field to add a requirement property for example
That field could look like requirement: ['users.*', 'companies.{id,name}']...

Tell me what you think about it @arnaudbesnier

I am not ok to remove flexibility here.

The day developers will update to the new (major?) version containing this code, they will potentially lose their Smart Field search feature (if they used include). There is no alternatives with the current code.

I am not fan of the requirement attribute idea as presented, because:

  • it is defined in the field but only impacts the search behaviour.
  • from my point of view, all this search configuration/implementation should be located in the search function.

@VincentMolinie
Copy link
Member Author

VincentMolinie commented Feb 28, 2020

Actually after thinking about it the include is useless as of right now the call is async so you can do your search on the other model if necessary and then do a id in [myListOfId] for example @arnaudbesnier

@arnaudbesnier
Copy link
Contributor

Ok, I think this something could also have with the current implementation.

What is important is what is removed.
With the new implementation, you won't have the ability to do it in a single SQL query anymore.

@VincentMolinie
Copy link
Member Author

Ok, I think this something could also have with the current implementation.

What is important is what is removed.
With the new implementation, you won't have the ability to do it in a single SQL query anymore.

yeah but like I said it won't work most of the time, because if you try to do it on many relationships it won't work. And belongsTo might work but not like you might expect...

@SteveBunlon SteveBunlon force-pushed the devel branch 2 times, most recently from 660dc77 to 9f305b9 Compare April 17, 2020 09:39
@arnaudbesnier arnaudbesnier changed the base branch from devel to master May 13, 2020 10:23
@arnaudbesnier arnaudbesnier removed their assignment Sep 5, 2022
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

Successfully merging this pull request may close these issues.

3 participants