I am trying to use the ?filter rest method, in order to query on nested properties. However, this doesn't seem to work:
/someResource?filter[where][field.subField][like]=abc
neither does this (which I think is wrong anyway):
/someResource?filter[where][field][subField][like]=abc
Any hints?
Which connector are you using?
Memory in dev, mongo in test and beyond. It's the memory connector that has the issues. We use this one for our dev setup as it resets upon restart...
It's the 'dot' notation that is working with mongo.
This is currently a limitation of the memory connector.
@raymondfeng perhaps we can use something like https://github.com/logicalparadox/filtr or https://github.com/crcn/sift.js to enable this
Well, the nice thing about the memory connector is that it resets, so you test every run with a clean sheet. And of course it's rather speedy ;-)
Of course - however, you can easily reset the test database before you start, like this:
app.datasources['db'].automigrate(next);
Will this drop the entire schema?
Yes, but in the case of MongoDB collections will be empties and indexes re-created. There's no real schema, like with SQL databases.
Sure. Just calling it a 'schema' as a 'habit'
Of course! While collections are being recreated, they are not really removed from the database first. So any obsolete collections will stay around, until you delete them, or the database itself. AFAIK loopback will create the db for you, in case it doesn't exist.
@fabien These libraries are interesting:
I also looked at:
Keep in mind, RDBs won't support nested queries.
@raymondfeng sift.js looks good to me, but it doesn't support skip/limit. nedb does, but it seems quite a bit more involved. It can probably be implemented as a new connector altogether.
Users should be made aware of the limits of RDBM's, which is perhaps easiest when having this as a separate connector - so users have to be explicit about it, instead of relying on the memory connector (for tests and so forth) to support any type (both SQL as well as NoSQL style) of query. It's probably easy to copy the mongodb connector's query normalization code and implement this.
Here are some more libraries of interest:
Loosely related: #683 How can i set condition where on include model
How this can work for mysql connector? I have same issue
Looks like Loopback currently does not support nested include filtering. This seems like a huge limitation. I don't believe the db connector should make any difference because ideally the Loopback framework would work the same regardless of what db connector you're using
i'm having the same problem trying to do a nested include. Any solution ?
So are there any plans to support nested properties? Is there any way to get the "native" mongodb-connection so we can query the database without the loopback abstraction?
Hey! I've got the Same Problem. I want to query a List of objects based on the property of an related model as well as the property of the wanted model e.g:
Event.find( { where: { and: [ { endDate : { lt : givenDate}}, { location.name : "Abc" }]} }, cb );
So, am I right, that this is not supported atm?
I want to query a List of objects based on the property of an related model as well as the property of the wanted model.
So, am I right, that this is not supported atm?
You are right, this it not supported yet.
so the easiest way would be to just query via SQL? Without any further knowlage: is there any caching mechanism I could use?
Can we upvote on this feature?
Sure, leave a comment containing one of :+1: or +1 (as regular text, not like I did).
:+1:
+1
+1
+1
:+1:
+1
+1
+1
+1
I guess we can make it happen for NoSQL DBs, but it will be difficult for RDBs.
+1
As far as I am concerned, a good start would be to support nested filters for embedded objects and embedded models.
+1
+1
+1
+1
+1
+1
+1
What databases are you using? Is it enough to support filtering on second-level properties for memory and MongoDB, or do you need it for SQL databases too?
https://github.com/strongloop/loopback-datasource-juggler/pull/544 is adding support for dot-notation to the memory connector, to make it consistent with MongoDB.
This should hopefully fix the issue for @daankets as described in his earlier comment:
Memory in dev, mongo in test and beyond. It's the memory connector that has the issues. We use this one for our dev setup as it resets upon restart...
It's the 'dot' notation that is working with mongo.
Implementing this feature for non-embedded relations (e.g. hasMany, belongsTo) and supporting SQL connectors (both embedded and non-embedded relations) requires significant amount of time, which we can't invest right now.
+1
Thanks for this! It's making testing quite a bit easier ;-)
+1
:+1:
+1
I really love the way PHP's Doctrine ORM has implemented this feature. For some databases filtering takes place on the database level. When a specific database connector does not support the filtering interface Doctrine does the filtering for you using PHP.
http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections
I understand it would take a lot of time to provide this feature for all databases, so perhaps it is an option to adapt such a pattern.
+1
+1
:+1:
+1
+1
+1
:+1:
+1
+1
+1
2015-07-10 11:24 GMT+02:00 David [email protected]:
+1
—
Reply to this email directly or view it on GitHub
https://github.com/strongloop/loopback/issues/517#issuecomment-120315877
.
+1 Using MySQL (sadly)
+1
+1
+1
+1
+1
+1 (Postgre)
+1 (Postgre)
+1
+1
+1
:+1:
For those who need this in SQL relations, I've created a fork of loopback-connector and already got something good.
Here's a example. Suppose that a model customer have many orders, then you can create a query like this:
var sql = connector.buildSelect('customer', {
where: {
vip: true,
orders: {
where: {
id: 42
}
}
}
});
// which results in
ParameterizedSQL {
sql: 'SELECT DISTINCT `CUSTOMER`.`NAME`,`CUSTOMER`.`VIP`,`CUSTOMER`.`ADDRESS` FROM `CUSTOMER` INNER JOIN ( SELECT `ORDER`.`CUSTOMERID` FROM `ORDER` WHERE `ORDER`.`ID`=$1 ORDER BY `ORDER`.`ID` ) AS `ORDER` ON `CUSTOMER`.`NAME`=`ORDER`.`CUSTOMERID` WHERE `CUSTOMER`.`VIP`=$1 ORDER BY `CUSTOMER`.`NAME`',
params: [ 42, true ]
}
with some line breaks for readability:
SELECT DISTINCT `CUSTOMER`.`NAME`,
`CUSTOMER`.`VIP`,
`CUSTOMER`.`ADDRESS`
FROM `CUSTOMER`
INNER JOIN (SELECT `ORDER`.`CUSTOMERID`
FROM `ORDER`
WHERE `ORDER`.`ID` = $1
ORDER BY `ORDER`.`ID`) AS `ORDER`
ON `CUSTOMER`.`NAME` = `ORDER`.`CUSTOMERID`
WHERE `CUSTOMER`.`VIP` = $1
ORDER BY `CUSTOMER`.`NAME`
You can already query multiples relations together and even nest then.
I will work more on this over the weekend and create some tests as well.
Regarding tests, my modifications didn't break any available tests, with the exception of one single line in the function columnEscaped, where I needed to add the table name before the column name to resolve some ambiguity problems. This broke a lot of tests, but the SQL output is still valid.
Hey @DiogoDoreto looks good.
What about REST filters?
Thanks.
@eugenehp buildSelect is a low level function that is used by REST filters, so they get the feature as well.
Would you mind @DiogoDoreto if I ask you to show me the similar query in the REST format (just the same one you posted above)?
Thank you.
I think it would be something like /customers?filter[where][vip]=true&filter[where][orders][where][id]=2.
It's important to note that orders is the name of the relation defined in customer model and that the value in it is a full filter, which means that besides where you can also use limit, order, etc
interesting. Thanks Diogo. I'll give it a try and let you know.
Have a great weekend ahead!
Cheers.
On Fri, Oct 16, 2015 at 9:57 PM, Diogo Doreto [email protected]
wrote:
I think it would be something like
/customers?filter[where][vip]=true&filter[where][orders][where][id]=2.It's important to note that orders is the name of the relation defined in
customer model and that the value in it is a full filter, which means
that besides where you can also use limit, order, etc—
Reply to this email directly or view it on GitHub
https://github.com/strongloop/loopback/issues/517#issuecomment-148819398
.
Thank you! if you are using loopback-connector-mysql you can change the dependency version on package.json to DiogoDoreto/loopback-connector-mysql#query-relations to get my modifications.
@DiogoDoreto Would you like to submit a PR? I can get the PR prioritized for review during sprint planning since everyone in the community really wants this feature.
+1
I use mongo connector and having error. Any help? Anything wrong with query string?
user obj
{
"profile": {
"username": "[email protected]"
}
}
?filter[where][profile.username][email protected]
{"error":{"name":"Error","status":404,"message":"Unknown \"user\" id \"undefined\".","statusCode":404,"code":"MODEL_NOT_FOUND"}}
It does not work with find REST API.
Anyway all of those info should be in this link :)
https://docs.strongloop.com/display/public/LB/Where+filter
+1
the dot notation doesn't seem to work with Angular SDK / mongo
eg:
Published.find({
filter: {
where: {
'post.id' : 'xyz'
}
}
}
returns no documents
Published.find({
where: {
'post.id' : 'xyz'
}
}
returns all the documents
+1
+1
+1
+1
Can I pledge a donation amount to ensure this issue is worked on in the near future?
@deweydb Haha, if things only worked that way. Let's do this, I will bump this to critical to make sure this comes up during sprint planning.
However, that said, it's still in triage status and we need to figure out all the use cases. If you guys could provide me with more sample repos, we can use them to create tests to make sure we get the coverage needed.
+1
I have data stored in JSON columns in Postgres - it would be nice if I could do nested filters there as well.
For example, something simple like:
{
"customerId": 0,
"customer": {},
"source": "string"
}
where the customer is a Object field with a postgres JSON column type (it displays as {} in the Explorer) and the customerId is an int with source as a string. I'd want to query/filter on something like customer.dateofbirth.
+1
+1
+1
:+1: for RDB
+1
+1
+1
+1 (Postgresql)
+1
+1 for mysql
+1 for mysql
+1
Viewing your scrum board I see that this is still in backlog. Is there any ETA on this considering there is already some PR work done?
+1
Using mongo connector I have discovered that the where filter does not work on nested properties where the value includes spaces:
{
"company" {
"name":"strongloop company"
}
}
/api/Customers/?filter[where][company.name][like]="strongloop comp"
does not work, however
/api/Customers/?filter[where][company.name][like]="strongloop"
does work
the same results for the "regexp" operator.
it looks like SL is not allowing spaces as literal, perhaps treating them as a end of string delimiter?
+1 PostgreSQL
+1
@joelosx Using mongo connector I have discovered that the where filter does not work on nested properties where the value includes spaces
please open a new GH issue to track that problem.
@PharaohMaster Viewing your scrum board I see that this is still in backlog. Is there any ETA on this considering there is already some PR work done?
I am afraid this isn't among our top priorities right now, I cannot give you any ETA.
+1
+1
:+1: (postgres)
+1
:+1:
+1
+1
+1 (mssql)
So far it's the work in progress:
https://github.com/strongloop/loopback-connector/pull/40
:+1:
:+1:
+1
+1
:+1:
+1
:+1:
+1
+1
+1
+1
+1
+1 oracle
+1 fields on nested attributes + dotted notation
+1
While waiting on this feature, I'd like to create a remoteMethod that does an INNER JOIN, resulting in the dataset I want, but I'd like to be able to keep a relatively similar filter/sort/order REST API parameter set if possible.
Is there any method to compile some of the query parameters into SQL? Or possibly a subset of the filters.
+1
+1 (Postgre)
:+1:
+1
+1
+1
+1
+1
+1 Using MySQL (not sadly)
+1 using mongo connector
The ability to query and filter/exclude data based on relations like belongsTo and hasMany is really very important. Please try to prioritize this!
+1
+1
+1 (mssql)
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1. This is seriously inconvenient, because the order of included relations isn't stable if limit changes, making it impossible to reliably paginate across them.
+1
👍
Hi,
I tried querying level 2 properties and i was able to get the data right.
Eg. I used
{"where": {"and": [{"name": "Eureka Outsourcing"},{"pocs.phone":{ "inq": [2225302400] }}, {"costToUs.name":{ "inq": ["Kiosk"] }}]}}
ON JSON Data:
{
"name": "Eureka Outsourcing",
"pocs": [
{
"name": "Hemchandra Pujari",
"phone": 2225302433,
"email": "[email protected]"
},
{
"name": "Ranshinghe",
"phone": 2225302400
}
],
"id": "5770feb6268c56b00cc708c6",
"costToUs": [
{
"name": "Kiosk"
}
]
}
What would be the trouble of making it work at RDBs, like MySQL or MsSQL?
@richardaum Apparently, given that this issue has been open since 2014, a lot.
FTR for anyone who finds this issue, I don't think this is related to INNER JOIN style queries as some like @jeff3yan have mentioned. The OP seems to be referring explicitly to querying on sub-properties of object properties. E.g if a use has an Address which is an object, querying on street number. The reason this isn't really possible in RDS (short of selecting all records and filtering manually) is because loopback stores Object properties as stringified JSON. The only other way might be to construct some sort of regexp that would apply to the underlying JSON string and querying on that.
As far as related (JOIN) queries go (e.g. find customers who have not made any purchases) that doesn't seem possible without executing SQL directly via ds.connector.execute. I believe that is a really important feature that would definitely be doable but probably warrants a separate issue.
+1 (For search features across related MySQL tables)
+1 Oracle DataBase
+1 (Postgre)
+1 (Oracle)
@zbarbuto just clarifying, but this issue is specifically related to filtering on object type properties of the current model, _not_ filtering on properties on related models?
If so, should there be another issue created for filtering on related model properties? I have seen this issue referenced in a few stackoverflow questions asking about filtering on related models, so still not 100% sure.
@jeff3yan I believe this is the case. You are correct in that many questions etc. link to this issue, but in reading @daankets op it sounds like he is referring to nested object properties only: /someResource?filter[where][field.subField][like]=abc.
I have already created an issue for related model properties issue over on loopback datasource juggler:
https://github.com/strongloop/loopback-datasource-juggler/issues/1042
I haven't had time to setup the sandbox demo for the issue yet but will do soon hopefully (or anyone else feel free to drop over to that issue and post one)
👍
+1 (Postgres)
+1 (Postgres)
+1 (Postgresql)
:+1: for Postgres
I have taken a look on how to do the filtering based on the included model in mongodb.
The current mongodb connector results in a query like this:
db.model1.find({"model2.recordNo": 123})
but model2 object is not included so we get zero results.
So, We need to include the related model first.
I've found that using aggregate method along with $match instead of find enables including the related model using $lookup like this:
db.model1.aggregate(
[
{$lookup: {
from:"model2",
localField: "model2Id",
foreignField: "_id",
as: "model2"
}},
{$match: {"model2.recordNo": 123}}
])
where model1 is the main model and model2 is the related model
this should return a set of model1 filtered based on the related model model property recordNo
Well, next I will try to implement the above code to be used in the mongodb connector.
It will be used based on two conditions
Please let me know your opinions on this, and if this is a good approach.
regards,
Mostafa
+1 (Postgresql)
+1
+1
Have there been any updates on this pull request? https://github.com/strongloop/loopback-connector/pull/40
strongloop/loopback-connector-mongodb/pull/301
So I went on my own and tried to make the dot notation work on non-embedded relations for mongodb.
And it's working for me now, I hope someone finds this helpful.
+1
+1
+1
+1 (MySQL)
+1 (postgre) This is really important to have
+1 (MYSQL
+1 (postgres)
+1 Mysql
Please, stop posting +1 comments which are only spamming all people subscribed to this thread. Instead, click on the big yellow "thumbs up" button at the top of this issue to upvote it.
elemMatch for array elements: https://github.com/strongloop/loopback-connector-cloudant/issues/78regex is used: https://github.com/strongloop/loopback-connector-cloudant/issues/77~SQL(N/A)~
Verification of the feature:
Verification done using a loopback app and connecting it to the three datasources mentioned above.
It worked with the three datasources.
Feature Verified
@jannyHou Why is SQL n/a? I feel like this should still be possible in Postgresql - but would require using the native JSON type for storage rather than strings as is done now.
@kjdelisle Closed? Does it mean I can now filter by 2 level properties using Postgres or MySQL?
@zbarbuto @kolach There's a more fundamental change coming in loopback 4 which might be able to support 2nd level filter across all connectors.
cc @raymondfeng
Can you elaborate more about our plan on supporting nested filter in sql connectors? Thanks :)
@zbarbuto Don't you think that this issue should be left open until you guys implement that filtering?
My bad; I closed this via ZenHub. I thought it was the internal issue we were using to track the work across our pipeline. Reopening this until it hits npmjs.
Thank you @kjdelisle
and when may LB4 be coming ?
@kjdelisle can you post a link to the documentation page that explains how this feature is now implemented?
cc @jannyHou
👍
+1
Guys, please stop posting +1 comments. You're waking up everybody. Use this icon in the top-right corner of the comment or original post you are consent with.

+1 for the suggestion or please use the unsubscribe button
El dom., 7 de may. de 2017 1:47 PM, Christiaan Westerbeek <
[email protected]> escribió:
Guys, please stop posting +1 comments. You're waking up everybody. Use
this icon in the top-right corner of the comment or original post you are
consent with.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/strongloop/loopback/issues/517#issuecomment-299726158,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA9bk7iBW_2rK5uj-bgzWJ2pC-8VZqQnks5r3hGmgaJpZM4Ccngj
.
Please in the next version of loopback-next, loopback-datasource-juggler use alias in the generated queries, for example buildWhere, buildSelect, buildColumnNames don't use alias, so if i want to take advantage of this method to build my custom find which includes other table joins , i have to manually process all generated sql and add the alias field by field! ALIAS in the new juggler is a must!! And support to add table joins to the find methods will be nice too :) an extra parameter joins something like joins:[{modelJoin:team,as:'teams',modelForeignKey:'user_id',associationKey:'id',joinWhere:[{teams.name:{inq:['admin','level 2'}].... that and a "having" condition to append to the end of parameterizedSQL :), I know is a lot, haha. loopback-next typescript + new juggler + fireloop = The perfect framework
+1
Please in the next version of loopback-next, loopback-datasource-juggler use alias in the generated queries, for example buildWhere, buildSelect, buildColumnNames don't use alias, so if i want to take advantage of this method to build my custom find which includes other table joins , i have to manually process all generated sql and add the alias field by field! ALIAS in the new juggler is a must!! And support to add table joins to the find methods will be nice too :) an extra parameter joins something like joins:[{modelJoin:team,as:'teams',modelForeignKey:'user_id',associationKey:'id',joinWhere:[{teams.name:{inq:['admin','level 2'}].... that and a "having" condition to append to the end of parameterizedSQL :), I know is a lot, haha. loopback-next typescript + new juggler + fireloop = The perfect framework
@tellex If you could formalize this into a new issue on loopback-next that would definitely get more eyes on your suggestion. :)
+1
[email protected] will turn to LTS soon, and we are sorry to say that we don't have plan or say bandwidth to implement the filter with related properties, or the filter applied on the nested model properties with SQL connectors.
In [email protected], our NoSQL connectors for Mongodb, Cloudant and [email protected] support query with nested model properties(not related properties), and everything regarding data persistence is open for discussion in https://github.com/strongloop/loopback-next.
I am closing this issue.
it`s very hard to write a non trivial application with good perfomance and clear code without this functionality. I think this should be seriously reconsidered if you plan to turn loopback in a robust framework for more complex applications.
@vanderdill This was the reason I posted about #3407 and created the objection-filter module.
The main disadvantage that I've found with the Loopback ORM is that the REST API filter is identical to the model filter.
It would be more useful to have more powerful queries directly on the model (joins etc.), and have a subset of those features exposed on the API.
I found a workaround for my issue. Posting it here for the community.
Some context : MySQL; I have a Company table and a Job table, each containing a published field. When I list all the jobs, I don't want published jobs from not-published companies to be returned.
I created a VIEW job_full that aggregates the whole row and the level 2 field I want to check :
CREATE VIEW job_full AS
SELECT job.*, company.published AS company_published
FROM job, company
WHERE company.id=job.company_id;
And linked the Job model to the fob_full table in the LB model definition.
That way, I can filter on company_published (which is done with an operation hook in my case).
create and updatework out of the box, as long as I don't pass a company_published property.
I had to override the destroy methods, though :
Job.on('dataSourceAttached', function() {
const JobRaw = app.models.JobRaw;
Job.destroyById = function(...args) {
return JobRaw.destroyById(...args);
};
Job.destroyAll = function(...args) {
return JobRaw.destroyAll(...args);
};
});
(where JobRaw is the LB model definition linked to the real job table)
It's hacky, and performance is likely to be crap, but it helps by the time you figure this issue out ;-)
Hey i finish the first alpha version of a model method extension for postgresql >= 9.2, it allow any deep of filter includes with features like: relation aliases, join types, new where condition syntax including the option for using functions in the where statement, a "having" condition for hasMany or hasManyThrough, orderBy option. It generates one big sql query using new features of postgres like json_build_object(), json_agg() and optimized new "LATERAL" join for join subqueries, thanks to this new postgres features the data serialization is done in the database returning the results with the corresponding relations structure, i tested it with the classic movie rental postgres database, i need help to test it in bigger databases.
Code and instructions:
https://github.com/tellex/findComplex
Looks like a good start @tellex .
I think it needs to utilize some of the existing loopback-connector to avoid SQL injection (https://github.com/tellex/findComplex/blob/master/findComplex.js#L647 for example should escape the column names, see: https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L456).
An alternative might be to leverage something like knex to build the queries (or parts of them) to get around this.
Congragulations for the initiative @tellex. i'll use it as soon as possible. It seems very nice.
@zbarbuto
If you look closely the code, i check if the name of the property exists in the model definition, since loopback properties naming convention i don't see how it can be possible to sql inject, column names can't be parameterized, the same goes for aliases can't be parameterized, i check alias names against a regex, the same regex and rules that are needed for javascript function names. When i encounter a value i parameterize it with the same library that loopback uses var ParameterizedSQL = require('loopback-connector/lib/parameterized-sql');
Then i use the same libraries that loopback uses for sql queries.
sql = this.datasource.connector.parameterize(mainSql);
this.datasource.connector.execute(sql.sql,sql.params,function(error,data){
cb(error,data);
});
I started using knex, but when i needed to define sql join subqueries knex have no support...
Knex is nice.. but is more for not so complex queries, keeps the code clean. I trashed 2 weeks of work because of knex. The code is hard to read, when i have more time i will comment it, some parts are complex because there is no other way than using recursive functions to generates the sql backwards.
Fair enough, sounds good. Really looking forward to testing it out.
FWIW, some support for querying nested properties was added by https://github.com/strongloop/loopback-datasource-juggler/pull/1239, plus https://github.com/strongloop/loopback-datasource-juggler/pull/1515 is going to fix coercion of nested values.
@tellex: After fixing two small bugs it worked very well! I think it is a very good starting point for those using postgres. Thank you for the initiative.
Since I had to copy the files of your repo to different places it's not so easy to provide you the fixes with a pull request…
in the doc i can read: Loopback supports filtering nested properties in three NoSQL connectors: Mongodb, Cloudant, Memory.
so a query like this it's impossible on mysql
User.find({where: {'address.tags.tag': 'business'}}
i can't see any valid workarount to achieve multiple join with where condition... that will require multiple queries leading performance issues (and resource waste)
any suggestion?
I am lost at the moment. This ticket is closed, but does filtering on nested properties work with mongodb?
@F3L1X79 It works as long as the nested properties are embedded on the same document.
This does not work for MySQL. It should be possible to translate something like:
User.find({where: {'address.tags.tag': 'business'}}
Into JSON_EXTRACT conditions instead of simple SQL equality.
Can someone point me in the direction of the code where the translation from JSON to SQL is done? Thanks.
@acrodrig I think most of the code you're looking for will be here: https://github.com/strongloop/loopback-connector-mysql/blob/master/lib/mysql.js.
Also for anyone interested - there is support for this to some degree in postrgres using the json data type as per this PR
https://github.com/strongloop/loopback-connector-postgresql/pull/304
Why the filter with property id does not work? If I change it to any other property name it works (ie: customer.name). I'm using mongodb connector.
// Does not work
var filter = {
where: {
'customer.id': customerId
},
order: 'order_number DESC'
}
// Works
var filter = {
where: {
'customer.name': customerName
},
order: 'order_number DESC'
}
Order.find(filter, function (err, orders) {..})
Hey @elviocb , this must be problem with customer.id stored as String and not ObjectId. Can you share how your Order model looks. It should be related to https://loopback.io/doc/ja/lb3/MongoDB-connector.html#strictobjectidcoercion-flag
hey @princecharmx .. thanks for your reply!
That's my order model definition:
{
"name": "order",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"status": {
"type": "string",
"required": true,
"default": "open"
},
"customer": {
"type": "object"
},
"customer_id": {
"type": "string"
},
"discounts": {
"type": [
"object"
]
},
"discount_codes": {
"type": [
"string"
]
},
"comissions": {
"type": [
"object"
]
},
"email": {
"type": "string",
"required": true
},
"cart": {
"type": "object"
},
"financial_status": {
"type": "string",
"required": true,
"default": "pending"
},
"tags": {
"type": "string"
},
"number": {
"type": "number",
"required": true,
"default": 1000
},
"order_number": {
"type": "number",
"required": true
},
"name": {
"type": "string",
"required": true
},
"subtotal_price": {
"type": "string",
"required": true
},
"total_discounts": {
"type": "string",
"required": true
},
"total_price": {
"type": "string",
"required": true
},
"total_tax": {
"type": "string",
"required": true
},
"total_comissions": {
"type": "string",
"required": true
},
"tax_lines": {
"type": [
"object"
]
},
"cancel_reason": {
"type": "any"
},
"canceled_at": {
"type": "date"
}
},
"validations": [],
"relations": {
"shop": {
"type": "belongsTo",
"model": "shop",
"foreignKey": "shop_id"
},
"customers": {
"type": "hasOne",
"model": "customer",
"foreignKey": "customer_id"
}
},
"acls": [],
"methods": {}
}
And this is how an order model is stored:
{
"_id" : ObjectId("5a9a9b3b4fd628739efb4972"),
"status" : "open",
"customer" : {
"name" : "Laila ",
"lastname" : "Gonçalves",
"email" : "[email protected]",
"gender" : "female",
"age" : "23",
"cpf" : "24898932100",
"id" : "5a9352c29fe55f9a981661a8",
"partner_id" : "5a80d66992856a1c701ab2c2"
},
"customer_id" : "5a9352c29fe55f9a981661a8",
"discounts" : [],
"discount_codes" : [],
"email" : "[email protected]",
"cart" : {
"items" : [
{
"id" : 994925047,
"product_id" : "5a77690bd3715f5127e10cff",
"title" : "Feijoada monster",
"price" : "14.90",
"quantity" : 1,
"image" : "https://dummyimage.com/400x400/000000/ffffff.jpg"
},
{
"id" : 518365228,
"product_id" : "5a77694ad3715f5127e10d00",
"title" : "Escondidinho Power",
"price" : "14.90",
"quantity" : 1,
"image" : "https://dummyimage.com/400x400/cc14cc/ffffff.jpg"
}
],
"subtotal_price" : "29.80",
"total_price" : "29.80",
"formatted_price" : "R$29.80",
"item_count" : 2,
"total_discount" : 0,
"discounts" : [],
"tax_lines" : [],
"total_taxes" : 0,
"allow_payment_method" : true,
"allow_discount_override" : false,
"payment_method" : {
"id" : "003",
"display_name" : "Dinheiro",
"name" : "money",
"short" : "d"
},
"customer" : {
"name" : "Laila ",
"lastname" : "Gonçalves",
"email" : "[email protected]",
"gender" : "female",
"age" : "23",
"cpf" : "24898932100",
"id" : "5a9352c29fe55f9a981661a8",
"partner_id" : "5a80d66992856a1c701ab2c2"
}
},
"financial_status" : "pending",
"tags" : "",
"number" : 1000,
"order_number" : 1002,
"name" : "#1002",
"subtotal_price" : "29.80",
"total_discounts" : "0.00",
"total_price" : "29.80",
"total_tax" : "0.00",
"total_comissions" : "5.60",
"tax_lines" : [],
"cancel_reason" : null,
"canceled_at" : null,
"shop_id" : ObjectId("5a8ddeba4f11315cb6076cc3"),
"comission_ids" : [
"5a9a9b3b4fd628739efb4973"
],
"id" : ObjectId("5a9a9b3b4fd628739efb4972")
}
You have incorrect model. You are having property customer and also have a relation customers with hasOne.
You should use either.
Also, as pointed note, your customer.id is stored as string and hence you are having problem.
Add strictObjectIDCoercion to true in above model.
"options": {
"validateUpsert": true,
"strictObjectIDCoercion": true
}
Fyi, your usage is incorrect at many places. First you confirm if my suggestion works. I will then guide you next steps.
Hey @princecharmx .. It works. Thanks!.. Could you guide me which other parts of the model are incorrect please?
I can't see valid solution for MYSQL inner join yet, has anyone found at least a workaround?
I've made a fork of loopback-connector-mysql to support joins. It's not an ideal solution but it works, I'm using it in production in my applications. It only supports read operations.
This is a filter working over the User built-in model, to find all users with an ADMIN name role (the relation between User and Role is needed):
{"where": {"roles": {"name": "ADMIN" }}}
You can check it out https://github.com/jolivervidal/loopback-connector-mysql
@jolivervidal just tested and that work perfectly !!! you save me a lot of time, why this is not included in the standard library? i'll check what you have done in your fork!
Right now we have a workaround solution for this case ? :( for mongoDB
@bellgetlinks For mongodb I've ended up opening a connection to mongodb in a boot script and running direct queries and filters on related models using .aggregate and $lookup through remote methods. Essentially sidestepping loopback.
I found this stack overflow post helpful for including related documents in queries.
This is the boot script I used to connect to mongodb and expose it as mongoDB for use in the models:
```'use strict';
const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = '< mongodb connection URL>';
// Database Name
const dbName = '< db name >';
module.exports = function connectToMongoDB(server) {
// Use connect method to connect to the server
MongoClient.connect(url).then(client => {
console.log("Connected successfully to server");
const db = client.db(dbName);
server.mongoDB = db
})
};
I've made a fork of loopback-connector-mysql to support joins. It's not an ideal solution but it works, I'm using it in production in my applications. It only supports read operations.
This is a filter working over the User built-in model, to find all users with an ADMIN name role (the relation between User and Role is needed):
{"where": {"roles": {"name": "ADMIN" }}}You can check it out https://github.com/jolivervidal/loopback-connector-mysql
@jolivervidal
Thanks dude, it works
I hope it won't create new errors on another things though
how about creating a PR on the official module about this feature you just made ? 😃
What's the status of this issue? Seems a very important feature is missing. @jolivervidal your fork seems working very well, why not merging with the master branch?
@michelgokan as you'll see from the thread:
Options are:
Thanks, @zbarbuto but none of your mentioned alternatives works, at least
for me at the moment:
I didn't find a problem in @jolivervidal fork at the moment. I hope nothing
bad happens 😬
On Sun, 3 Mar 2019 at 23:43, zbarbuto notifications@github.com wrote:
@michelgokan https://github.com/michelgokan as you'll see from the
thread:
- There is some support in postgres connector
https://github.com/strongloop/loopback/issues/517#issuecomment-362767424- Mongo also has some basic support (only for dot nested properties)
- Further support isn't going to be added to other RDB connectors as
loopback 3 is in LTS and no longer accepting new feature PRs- Loopback 3 ends LTS at the end of 2019 so it's even less likely to
be added.Options are:
- Write the custom SQL yourself as a custom endpoint
- Create an alternate connector for something like Knex
https://knexjs.org/ or Bookshelf https://bookshelfjs.org/ that has
support (big job)- Do the filtering in memory
- Use json for the nested data to use dot queries in something like
mongo or postgres- Look at migrating to loopback next which may add support in the
future—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/strongloop/loopback/issues/517#issuecomment-469072881,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AARH6W9n5vY5vqmX9fyotI6573Hl__nfks5vTFArgaJpZM4Ccngj
.
Does anyone know if the loopback datasource is compatible with the knex connector? It'd be great to use the same connections for both, to migrate to knex if possible. Then wrap around something like objection.js for filtering on nested relations.
Does anyone know if the loopback datasource is compatible with the knex connector?
@jeff3yan You'd have to write your own loopback-knex-connector. I've tried a few times but it's a big job and never really got anywhere with it. Having said that it would be an amazingly useful took if someone did manage to crack it. Particularly since join style queries (include) are pretty inefficient in loopback.
@michelgokan if that fork is working for you with MySQL then sounds like a good solution. I agree it's an unfortunate situation for users of other RDBs (like Postgres) but it's just the way loopback works - it does not assume your models are in any particular datasource so it does not leverage the full power of the underlying datasource (you _may_ be querying two models in postgres or one might be in postgres and one might be in Mongo - it makes no assumptions)
@tellex solution works very well for PostgreSQL. Thank you so much!
I've tested many scenarios, with where conditions and order/limit situations and it is exactly what I needed.
Code and instructions:
https://github.com/tellex/findComplex
For those who are using PostgreSQL I'm using @tellex solution, and it's working greate on a large project.
I've done some bug fixes and I'm keeping this fork updated with it:
https://github.com/vanderdill/findComplex
Most helpful comment
it`s very hard to write a non trivial application with good perfomance and clear code without this functionality. I think this should be seriously reconsidered if you plan to turn loopback in a robust framework for more complex applications.