Search code examples
loopbackjs

lookback API where filter with multiple conditions


When using loopback API, is 'AND' operator redundant in 'where' filter with multiple conditions? For example, I tested the following two queries and they return the same result:

<model>.find({ where: { <condition1>, <condition2> } });
<model>.find({ where: { and: [<condition1>, <condtion2>] } });

To be more specific, suppose this is the table content:

name   value
----   -----
a      1
b      2

When I execute 'find()' using two different 'where' filters, I get the first record in both cases:

{ where: { name: 'a', value: 1 } }
{ where: { and: [ { name: 'a'}, { value: 1 } ] } }

I've read through the API documents, but didn't find what logical operator is used when there are multiple conditions. If 'AND' is redundant as shown in my test, I prefer not using it. But I just want to make sure if this is true in general, or if it just happens to work with postgreSQL which I'm using.


Solution

  • This is a valid query which could only be accomplished with an and statement.

      {
        "where": {
          "or": [
            {"and": [{"classification": "adn"}, {"series": "2"}]},
            {"series": "3"}
          ]
        }
      }
    

    EDIT: https://github.com/strongloop/loopback-filters/blob/master/index.js

    function matchesFilter(obj, filter) {
      var where = filter.where;
      var pass = true;
      var keys = Object.keys(where);
      keys.forEach(function(key) {
        if (key === 'and' || key === 'or') {
          if (Array.isArray(where[key])) {
            if (key === 'and') {
              pass = where[key].every(function(cond) {
                return applyFilter({where: cond})(obj);
              });
              return pass;
            }
            if (key === 'or') {
              pass = where[key].some(function(cond) {
                return applyFilter({where: cond})(obj);
              });
              return pass;
            }
          }
        }
        if (!test(where[key], getValue(obj, key))) {
          pass = false;
        }
      });
      return pass;
    }
    

    It iterates through the keys of the where object where looking for failure, so it acts like an implicit and statement in your case.

    EDIT 2: https://github.com/strongloop/loopback-datasource-juggler/blob/cc60ef8202092ae4ed564fc7bd5aac0dd4119e57/test/relations.test.js

    The loopback datasource juggler contains tests which use the implicit and format

    {PictureLink.findOne({where: {pictureId: anotherPicture.id, imageableType: 'Article'}},
    
    {pictureId: anotherPicture.id, imageableId: article.id, imageableType: 'Article',}