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

Query by relations, yet another version #42

Closed
wants to merge 20 commits into from

Conversation

kolach
Copy link

@kolach kolach commented Mar 28, 2016

Schema

Models:

    Customer = ds.createModel('customer', {
      name: {
        id: true,
        type: String
      },
      vip: {
        type: Boolean
      },
      address: String
    });

    Store = ds.createModel('store', {
      id: {id: true, type: String},
      state: String
    });

    Retailer = ds.createModel('retailer', {
      id: {id: true, type: String},
      name: String
    });
    // Relations
    Customer.belongsTo(Store, {as: 'store', foreignKey: 'store_id'});
    Store.belongsTo(Retailer, {as: 'retailer', foreignKey: 'retailer_id'});

Query by retailer name brings 2 INNER JOINS:

  it('builds SELECT with deep inner join', function() {
    var sql = connector.buildSelect('customer',
      {order: 'name', limit: 5, where: {store: {retailer: {name: 'oxxo'}}}});
    expect(sql.toJSON()).to.eql({
      sql: 'SELECT `CUSTOMER`.`NAME`,`CUSTOMER`.`VIP`,`CUSTOMER`.`ADDRESS`,' +
      '`CUSTOMER`.`STORE_ID` FROM `CUSTOMER`' +
      ' INNER JOIN `STORE` ON `CUSTOMER`.`STORE_ID`=`STORE`.`ID`' +
      ' INNER JOIN `RETAILER` ON `STORE`.`RETAILER_ID`=`RETAILER`.`ID`' +
      ' WHERE `RETAILER`.`NAME`=$1 ORDER BY `CUSTOMER`.`NAME` LIMIT 5',
      params: ['oxxo']
    });
  });

Order clause brings LEFT JOIN:

  it('builds SELECT with left inner and outer joins because', function() {
    var sql = connector.buildSelect('customer',
      {where: {store: {state: 'NY'}}, order: {store: {retailer: 'name'}}, limit: 5});
    expect(sql.toJSON()).to.eql({
      sql: 'SELECT `CUSTOMER`.`NAME`,`CUSTOMER`.`VIP`,`CUSTOMER`.`ADDRESS`,' +
      '`CUSTOMER`.`STORE_ID` FROM `CUSTOMER`' +
      ' INNER JOIN `STORE` ON `CUSTOMER`.`STORE_ID`=`STORE`.`ID`' +
      ' LEFT JOIN `RETAILER` ON `STORE`.`RETAILER_ID`=`RETAILER`.`ID`' +
      ' WHERE `STORE`.`STATE`=$1 ORDER BY `RETAILER`.`NAME` LIMIT 5',
      params: ['NY']
    });
  });

To make it work for REST HTTP requests I had to modify loopback-datasource-juggler. Method:

DataAccessObject._normalize = function (filter) {

I commented out all the logic about order parameter processing. As I need it to accept more complex objects. (But string and array are also supported)

@slnode
Copy link

slnode commented Mar 28, 2016

Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test."

@christiaanwesterbeek
Copy link

Compare these where the first finds records where a customer field name matches a regexp and the second finds records where a joined table's field matches a value.
Customers.find({"where": {"name": {"regexp": '^T'}}});
Customers.find({"where": {"store": {"state": 'NY'}}});

I think table names as properties introduces ambiguity with existing conventions of filtering. Or is it a flexibility we should embrace, being backed by the model that will decide whether a table name or field name was meant?

How about this convention:

Customers.find({"where": {"store.state": 'NY'}});

PS: I should probably discuss this in some issue instead of this PR...

@raymondfeng
Copy link
Contributor

@devotis store should be the name of relation.

@raymondfeng
Copy link
Contributor

@kolach Thank you for the patch. Have you incorporated/merged changes from #41?

@christiaanwesterbeek
Copy link

@raymondfeng Ah yes. Thanks. After giving it a second thought, the convention proposed by @kolach might be just fine. Thanks for your contribution @kolach . I'll probably be using it soon.

@kolach
Copy link
Author

kolach commented Mar 28, 2016

@raymondfeng Sorry, I didn't have a chance to use the code from #41, as I was playing with my fork in parallel with @LoicMahieu

My PR is only about inner (for where clause) and left outer (for order clause) joins of belongsTo relations.

There are now three PR about the same subject. So I really hope the loopback team can choose the best options and let us finally have that feature in near future ;)

@raymondfeng
Copy link
Contributor

@kolach Two comments:

  • Does your PR only handle belongsTo relation?
  • I'm not sure if the limit property inside order is good idea. Is it different to have a top-level limit under filter?

@kolach
Copy link
Author

kolach commented Mar 29, 2016

@raymondfeng

  1. belongsTo only. As I do not have practical application of joining to hasMany right now. Can you think of something?

  2. About limit. I'm not sure that I understand. limit and offset are params that have nothing to do with order that params are added after ORDER BY clause. Why do you ask?

@raymondfeng
Copy link
Contributor

@kolach Please ignore 2. I misread your example and thought the limit property is inside order.

@kolach
Copy link
Author

kolach commented Apr 5, 2016

Hi @raymondfeng! Is anything that I can do to speed up the process?

@LoicMahieu LoicMahieu mentioned this pull request Apr 5, 2016
@Amir-61
Copy link
Contributor

Amir-61 commented Apr 6, 2016

Connect to : #31

Related to: #40 #44

Related GH issue: strongloop/loopback#517

@kolach
Copy link
Author

kolach commented Apr 16, 2016

Hi @raymondfeng, do you still want to finish #44 first? With all respect... I do not any see any progress for 8 days.

@jbcpollak
Copy link

@raymondfeng The Loopback issue this PR fixes (strongloop/loopback#517) is extremely popular, is there any chance you could give @kolach feedback on what needs to be done to merge this?

@bostondv
Copy link

@kolach @raymondfeng are you guys still considering merging in this PR? We need this functionality in a project of ours using loopback and I'd be happy to help.

In fact, I forked @kolach's branch and added a couple fixes: https://github.com/bostondv/loopback-connector/tree/query-relation

  • Synced up branch with master
  • Changing comparison operators from == to === broke find in MySQL connector
  • count was broken querying related models because it was missing the INNER JOIN statement

Lastly, does anyone have ideas how this might be amended to include support for hasMany relations?

Thanks!

@slnode
Copy link

slnode commented Oct 26, 2016

Can one of the admins verify this patch?

1 similar comment
@slnode
Copy link

slnode commented Oct 26, 2016

Can one of the admins verify this patch?

@kolach
Copy link
Author

kolach commented Oct 26, 2016

@bostondv: that's cool, can you send me PR to my kolach branch please? I'm not a part of the team so it's not up to me to merge it to loopback. Joins are not the only thing that is not implemented, DISTINCT, GROUP BY are also missing. So @bostondv you need to think carefully before going forward with loopback in production.

@stale
Copy link

stale bot commented Aug 22, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@slnode
Copy link

slnode commented Aug 22, 2017

Can one of the admins verify this patch?

@stale stale bot removed the stale label Aug 22, 2017
@kolach
Copy link
Author

kolach commented Aug 22, 2017

It's now funny to read my more than one year old comments: ...I do not any see any progress for 8 days..

@stale
Copy link

stale bot commented Oct 21, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@slnode
Copy link

slnode commented Oct 21, 2017

Can one of the admins verify this patch?

@stale stale bot added stale and removed stale labels Oct 21, 2017
@stale
Copy link

stale bot commented Oct 21, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 21, 2017
@stale
Copy link

stale bot commented Oct 21, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

1 similar comment
@stale
Copy link

stale bot commented Oct 21, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale
Copy link

stale bot commented Nov 4, 2017

This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository.

@stale stale bot closed this Nov 4, 2017
@0candy 0candy removed the backlog label Nov 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.