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

isSet query operator #1009

Closed
ritch opened this issue Jan 14, 2015 · 40 comments
Closed

isSet query operator #1009

ritch opened this issue Jan 14, 2015 · 40 comments

Comments

@ritch
Copy link
Member

ritch commented Jan 14, 2015

We should add support for something like this:

{
  where: {
    someField: {
      isSet: false
    }
  }
}

This would allow you to query for undefined fields using $isset in mongodb and NULL in SQL databases.

@ritch
Copy link
Member Author

ritch commented Jan 14, 2015

@bajtos
Copy link
Member

bajtos commented Jan 14, 2015

Well if we can't use { where: { someField: null } }, then isSet makes sense.

@raymondfeng
Copy link
Member

We can use { where: { someField: null } } today but the semantics is different for NoSQL DBs. For example, in Mongo,

someField: null ==> someField: {$type: 10}
someField: {isSet: false} ==> someField: {$exists: 10}

I'm fine to introduce connector specific extensions. Each connector should validate such extensions and report errors if a given operator or syntax is not supported.

@bajtos
Copy link
Member

bajtos commented Jan 15, 2015

We can use { where: { someField: null } } today but the semantics is different for NoSQL DBs.

Yeah, I was sort of expecting that, in wich case null is not a solution. Since LoopBack is promising to provide single API working on all databases, we need a solution that works consistently in all supported databases.

@marcellodesales
Copy link

@bajtos @raymondfeng is there any timeframe when this feature makes the cut?

@bajtos
Copy link
Member

bajtos commented Mar 24, 2015

@marcellodesales not really. Can you contribute the feature yourself?

@jsheely
Copy link

jsheely commented Mar 24, 2015

This already works using the exists method.

// REST Url
// /api/<modelName>?filter[where][<propertyName>][exists]=<true|false>

modelName.find({
    where: {
        propertyName: {
            exists: true
        }
    }
}, callback)

The key is https://github.com/strongloop/loopback-connector-mongodb/blob/master/lib/mongodb.js#L488 where it will apply the $ sign to any property it doesn't understand as an else case.

@kraman
Copy link
Contributor

kraman commented Mar 24, 2015

@jsheely That is specific to mongodb. would be nice if this could be generalized to all dbs.

@jsheely
Copy link

jsheely commented Mar 24, 2015

@kraman Agreed. I just wanted to be clear that this feature technically can work today. This and the related issues make it seem like it wasn't possible.

While it is not a baked part of the abstracted API it is very nice that it can fall down into the specific implementations of the provider and still be handled.

@raymondfeng
Copy link
Member

@kraman What's your expectation for relational DBs? Do you interpret exists: true as IS NOT NULL?

@kraman
Copy link
Contributor

kraman commented Mar 24, 2015

@raymondfeng yes, typically it would be IS NOT NULL

@marcellodesales
Copy link

@jsheely I agree with that being available in the API, as well as with @kraman around "IS NOT NULL" on relational db...

@kblcuk
Copy link

kblcuk commented May 11, 2015

@jsheely, the approach you mentioned doesn't work with current datasource-juggler when it coerces where clause:
https://github.com/strongloop/loopback-datasource-juggler/blob/128665f1bd403b94a08a55a230a496e838c47347/lib/dao.js#L926

@dhirenderbp
Copy link

nothing is working for the existence of a field in a document.

@arealmaas
Copy link

+1. Having the same probem as @kblcuk

@pmoelgaard
Copy link

Isn't this a very common use case, I cant believe there is no solution ?

@kblcuk
Copy link

kblcuk commented Sep 7, 2015

@pmoelgaard we've worked around it by introducing isDateSet property for model (defaulting to false since default for date in question is null), with which we can search for models which don't have date set.
This is suboptimal, though, and hopefully this issue will be eventually resolved.

@rawrmaan
Copy link

This is redonk. High priority for my team +5

@gausie
Copy link
Contributor

gausie commented Nov 23, 2015

The automatic passthrough of unrecognised properties actually doesn't work for this on MongoDB.

@gausie
Copy link
Contributor

gausie commented Nov 23, 2015

The reason for this bug lies with this line

https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/dao.js#L1238

In my case, the property I am inspecting is of boolean type. My { exists: true/false } object will be converted to true by this line because DataType is the Boolean constructor.

@gausie
Copy link
Contributor

gausie commented Nov 23, 2015

A possible solution for this would be to have the coercion skipped if the value is an object?

@barocsi
Copy link

barocsi commented Feb 4, 2016

For example see this

{last_vote_date: {exists: true}

throws an error

stack: "Error: Invalid date: [object Object]↵    at DateType 

So how should this be resolved? Any workaround?

@kblcuk
Copy link

kblcuk commented Feb 4, 2016

@barocsi #1009 (comment)

Another option I guess would be to init that date during beforeSave hook to be 0 ('1970-01-01', or something like that), and make your code to treat it like null.

@barocsi
Copy link

barocsi commented Feb 4, 2016

Thanks! But pre-filling the with database with unneeded data, just for the sake of a inappropriate (re-)implementation of an efficient mongodb query wrapper seems a bad practice.

@jsheely
Copy link

jsheely commented Feb 14, 2016

Currently the DAO breaks this functionality for the mongoDB fall through $exists check.

} else if (!((operator === 'like' || operator === 'nlike') && val instanceof RegExp)) {
          //val = DataType(val);  // Remove this use the object instead of passing "[object Object]" as the value
}

https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/dao.js#L1496

@lautarodragan
Copy link

lautarodragan commented Aug 4, 2016

This is needed for couchbase as well! Any updates on the implementation of this feature?

@sundeepgupta
Copy link

I'm finding that the nlike operator is working as a workaround in my particular case, which is for a MongoDB connector and string type property.

Account.find({where: {analyticsId: {nlike: ''}}})

@Ijmir
Copy link

Ijmir commented Oct 19, 2016

+1
can't query date field with exists - throws error when trying to cast it to date.
any update on this?

@tamitutor
Copy link

+1
Trying to send a query via the REST api. Want to return Mongo documents where a particular field does NOT exist.

@tamitutor
Copy link

tamitutor commented Dec 17, 2016

Never mind, figured out I was spelling "exists" as "exist"...For any one interested here is how to do it with stringified JSON via REST (with MongoDb as the data repo):

{"include": ["from", "to", {"relation": "childMessages", "scope": {"order": "created DESC", "include": ["from", "to"]}}, "parentMessage"], "order": "created DESC", "where": {"parentId": {"exists": false}}}

@Sanbornzhang
Copy link

Sanbornzhang commented Mar 15, 2017

maybe sometime filter have $ should continue ?
cause I always need field:{$operator: value}
if field instanceof Model and key match ^$ then continue ?

@idushes
Copy link

idushes commented May 14, 2017

module.exports = function(server) { let APIConnector; APIConnector = server.datasources.mongo.connector; return APIConnector.observe('before execute', function(ctx, next) { if (ctx && ctx.req && Array.isArray(ctx.req.params)) { ctx.req.params.forEach(function (param) { Object.keys(param).forEach(function (key) { if (param[key] && param[key]["$type"] === 10) param[key] = null; }); }) } next(); }); };

@idushes
Copy link

idushes commented May 14, 2017

screenshot 2017-05-14 11 15 16

@stale stale bot added the stale label Aug 23, 2017
@stale
Copy link

stale bot commented Aug 23, 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.

@jawadrehman
Copy link

got this error with a date type as well. Have to add null data :(

@stale stale bot removed the stale label Aug 30, 2017
@akvaliya
Copy link

I am also getting this issue.
Works for exists:true, but doesn't work for exists:false

@stale
Copy link

stale bot commented Dec 25, 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 Dec 25, 2017
@stale
Copy link

stale bot commented Jan 8, 2018

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 as completed Jan 8, 2018
@bartlettpsj
Copy link

It is still an issue!

@SippieCup
Copy link

Guessing now that we are in active LTS this wont be fixed :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests