Assuming the standard example of physicians and patiens used by StrongLoop (https://docs.strongloop.com/display/public/LB/HasManyThrough+relations):
common/models/physician.json
{
"name": "Physician",
"base": "PersistedModel",
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"patients": {
"type": "hasMany",
"model": "Patient",
"foreignKey": "patientId",
"through": "Appointment"
},
common/models/patient.json
{
"name": "Patient",
"base": "PersistedModel",
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"physicans": {
"type": "hasMany",
"model": "Physician",
"foreignKey": "physicianId",
"through": "Appointment"
},
common/models/appointment.json
{
"name": "Appointment",
"base": "PersistedModel",
"properties": {
"appointmentDate": {
"type": "date"
}
},
"validations": [],
"relations": {
"physician": {
"type": "belongsTo",
"model": "Physician",
"foreignKey": "physicianId"
},
"patient": {
"type": "belongsTo",
"model": "Patient",
"foreignKey": "patientId"
},
how can I get patient from physician filtering by appointmentDate?
I tried to use something like this:
Physician.findOne({
"where": {"id": physId},
"include": {
"relation": "patients",
"scope": {
"where": {
"appointmentDate": { "gt": fixedDate }
}
}
}
}, callback);
but it seems that Loopback look for appointmentDate on Patient model instead of on Appointment model.
Some useful hint?
Thanks!
I think you may have something wrong in your mongo query understanding.
The operators in mongo must in the beginning of '$', so your gt should change to $gt, where should change to $where
To get patient from physician filtering by appointmentDate, we can do it by 2 steps, suppose you have the id(physId) of a specific physician.
var appointments = Appointment.find({
"relation.physician.foreignKey": physId,
"properties.appointmentDate": { $gt: fixedDate }
}); // get all appointments after fixedDate
var patients = [];
appointments.forEach(function(appoint) {
patients.push(appoint.relation.patient);
})
return patient; // all patients in appointments
in node API
I have read the find method in doc, it use where filter to match value of specific field, but I think it is similar as the origin :-)
Appointment.find({
"relation.physician.foreignKey": physId,
"properties.appointmentDate": { gt: fixedDate }
})
and then you can use some method like _.forEach(underscore.js)to get the patients from the result
I wish it can solve your problem;
Related
I'm using loopback 3 to build a backend with mongoDB.
So i have 3 models: Object, Attachment and AwsS3.
Object has a relation Embeds2Many to Attachment.
Attachment has a relation Many2One to AwsS3.
Objects look like that in mongoDB
[
{
"fieldA": "valueA1",
"attachments": [
{
"id": 1,
"awsS3Id": "1234"
},
{
"id": 2,
"awsS3Id": "1235"
}
]
},
{
"fieldA": "valueA2",
"attachments": [
{
"id": 4,
"awsS3Id": "1236"
},
{
"id": 5,
"awsS3Id": "1237"
}
]
}
]
AwsS3 looks like that in mongoDB
[
{
"id": "1",
"url": "abc.com/1"
},
{
"id": "2",
"url": "abc.com/2"
}
]
The question is: how can i get Objects included Attachment and AwsS3.url over the RestAPI?
I have try with the include and scope filter. But it didn't work. It look like, that this function is not implemented in loopback3, right? Here is what i tried over the GET request:
{
"filter": {
"include": {
"relation": "Attachment",
"scope": {
"include": {
"relation": "awsS3",
}
}
}
}
}
With this request i only got the Objects with Attachments without anything from AwsS3.
UPDATE for the relation definitons
The relation from Object to Attachment:
"Attachment": {
"type": "embedsMany",
"model": "Attachment",
"property": "attachments",
"options": {
"validate": true,
"forceId": false
}
},
The relation from Attachment to AwsS3
in attachment.json
"relations": {
"awsS3": {
"type": "belongsTo",
"model": "AwsS3",
"foreignKey": ""
}
}
in AwsS3.json
"relations": {
"attachments": {
"type": "hasMany",
"model": "Attachment",
"foreignKey": ""
}
}
Try this filter:
{ "filter": { "include": ["awsS3", "attachments"]}}}}
I'm using Loopback 4.1.0 (generator-loopback#5.5.0 loopback-workspace#4.0.0).
I have an extended User model called 'Client', which holds all the information about the users.
I have a PersistedModel called 'Chat', which holds things like creation, last message.
I am trying to setup the relations between the two.
A Chat can have 2 or more members.
A Client can have none or many chats.
Ultimately, I need a way of finding out if a one-to-one chat exists between the logged in Client, and the Client being browsed.
I thought I'd cracked it, but it's just returning a blank object when I GET /Client/{ClientID}/chats
// client.json
...
"relations": {
"chats": {
"type": "hasMany",
"model": "Chat",
"foreignKey": "clientId",
"options": {
"validate": true,
"forceId": false
},
"through": "ChatMembership"
}
}....
// chat.json
...
"relations": {
"members": {
"type": "hasMany",
"model": "Client",
"foreignKey": "chatId",
"options": {
"validate": true,
"forceId": false
},
"through": "ChatMembership"
}
}....
// chat-membership.json
{
"name": "ChatMembership",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"joined": {
"type": "date",
"defaultFn": "now"
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": ""
},
"chat": {
"type": "belongsTo",
"model": "Chat",
"foreignKey": ""
}
},
"acls": [],
"methods": {}
}
I think you may need to define the foreign key in the chat-membership.json
I am trying to implement composite ids with Loopback 3.0.0 using MongoDB. each pair of product_id/keyword should be unique...
I check the official documentation:
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#data-mapping-properties
Here my model:
{
"name": "comparative",
"plural": "comparative",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"product_id": {
"id": true,
"type": "string",
"required": true
},
"keyword": {
"id": true,
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Although, all my attempts to make composite ids of product_id/keyword failed.
When I POST:
// 1st POST Success.
{
"product_id": "string",
"keyword": "string"
}
// 2nd POST Success.
{
"product_id": "string1",
"keyword": "string"
}
// 3rd POST FAILED -> I want it to success
{
"product_id": "string",
"keyword": "string1"
}
Any ideas?
Even after that, I need to keep an auto-generated MongoDB id just to keep track of the objects.
I tried with "idInjection", not working along with composite ids... (not generating anything...)
If I add another field "id" with generated set to true, composite ids doesn't work at all (contrary as before where it worked partially)
Thank you,
You can declare a composite index between product_id and keyword:
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#indexes
{
"name": "comparative",
"plural": "comparative",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"product_id": {
"type": "string",
"required": true
},
"keyword": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {},
"indexes": {
"productid_keyword_index": {
"keys": {
"product_id": 1,
"keyword": -1
},
"options": {
"unique": true
}
}
}
}
You don't have to put id: true in the properties. This is done only to a single field, if you don't want the default identification ie. _id in mongo
"properties": {
"product_id": {
"type": "string",
"required": true
},
"keyword": {
"type": "string",
"required": true
}
}
I assume that you have another model Product to which you want relate this model. In order to achieve this, add relations
check this loopback documentation to do so.
Hope this helped
I'm trying to order a request by relational data but I can't get it working:
Model 1:
{
"name": "model1",
"base": "PersistedModel",
"properties": {
"prop1": "string"
},
"relations": {
"model1": {
"type": "belongsTo",
"model": "model2",
"foreignKey": "model2"
}
}
}
Model 2:
{
"name": "model2",
"base": "PersistedModel",
"properties": {
"prop2": "string"
}
}
The REST API request filter I'm trying is this:
{
"include": [
{
"relation": "model2",
"scope": {
"order": "model2.prop2 ASC"
}
}
]
}
I don't get an error but the list is still unordered.
Any hints?
I'm using Loopback.io, with MongoDB. I can't figure how to use the "include" filter.
The goal is to have "theuser" be included fully in the "group" when done a find() or findOne(). All I get now is the id's in an array. Thanks
theuser.json:
{
"name": "theuser",
"plural": "theusers",
"base": "User",
"idInjection": true,
"properties": {
"peerId": {
"type": "string",
"required": false
},
"peerStatus": {
"type": "string",
"required": false
}
},
"validations": [],
"relations": {
"notes": {
"type": "hasMany",
"model": "note",
"foreignKey": "ownerId"
},
"groups": {
"type": "hasMany",
"model": "group",
"foreignKey": "groupId"
}
},
group.json:
{
"name": "group",
"plural": "groups",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"host": {
"type": "belongsTo",
"model": "theuser",
"foreignKey": "ownerId"
},
"clients": {
"type": "hasMany",
"model": "theuser",
"foreignKey": "clientId"
}
},
"acls": [],
"methods": []
}
I'm trying to find a group like so:
Group.findOne({
filter: {
where: {"ownerId": 1},
include: {relation: "clients"}
}
}
Group.findOne({
where: {
ownerId: 1
},
include: 'clients'
}, cb);