到目前为止,我已收到一些关于Parse承诺的优秀信息,并准备将这个难题吸收到我身上......关系关系。以下代码在很大程度上是回答Issues with Parse Cloud Code Promises,但我在下一个问题的部分代码的注释中有。我如何进一步询问顶级关系中的关系?很高兴看到你如何扩展代码来实现@ roamer-1888
最新:
//Return a single project
Parse.Cloud.define('getProjectByUrl', function(request, response) {
var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
var query = new Parse.Query(Projects);
query.equalTo('projectUrl', request.params.projectUrl);
query.include("projectStatus"); // *MJ Added the include to add the project Status pointer
query.find().then(function(projectsResult) {
var project = projectsResult[0];
//From here, `project` is hierarchically monkey-patched with the results of further queries.
//Make tags query, the referees query and the sections query in parallel.
var tagsPromise = project.relation('tags').query().find();
var refereesPromise = project.relation('referees').query().find();
var sectionsPromise = project.relation('sections').query().include("sectionType").find(); //*MJ Added the include of the sectionType pointer
// Aggregate the three promises with Parse.Promise.when(), and handle the responses.
return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise).then(function(tags, referees, sections) {
project.set('tags', tags);
project.set('referees', referees);
project.set('sections', sections);
//Go deeper into `sections`
var sectionsRelationsPromises = sections.map(function(section) {
// *MJ Remove sectionTypesPromise as it's a pointer
var filesPromise = section.relation('files').query().include("fileType").find(); // *MJ Added the include to grab the fileType pointer
return Parse.Promise.when(filesPromise).then(function(files) {
//*MJ Removed the promise for section Types
section.set('files', files);
// *MJ Removed the Deeper Logic
});
});
return Parse.Promise.when(sectionsRelationsPromises);
}).then(function() {
return project;
});
}).then(function(project) {
// At this point, all the data is gathered in the form of Parse objects in project,
// which now needs to be mapped into a js plain object.
var projectData = projectObj(project);
projectData.tags = project.get('tags').map(tagObj); //Process the tags response
projectData.referees = project.get('referees').map(refereeObj); // *MJ removed one e from refereeObj //Process the referees response
projectData.sections = project.get('sections').map(sectionObj); //Process the sections response
// *MJ Removed the adding of the files and looking over the sections.
//Yay! (hopfully)
response.success(projectData);
}).fail(function(error) {
response.error('Error: ' + error);
});
// ***********************************
// ***** start: mapper functions *****
// ***********************************
function projectObj(project) {
return { // *MJ Removed the stray equals sign here
'id': project.id,
'title': project.get('title'),
'previewImage': project.get('previewImage'),
'longDescription': project.get('longDescription'),
'shortDescription': project.get('shortDescription'),
'visibleToPublic': project.get('visibleToPublic'),
'dateStart': project.get('dateStart'),
'dateEnd': project.get('dateEnd'),
'updatedAt': project.get('updatedAt'),
"projectStatus": project.get("projectStatus").get("status") //*MJ Added the get of the Project Status status.
}
}
function tagObj(tag) {
return {
'tag': tag.get('tag')
};
}
function refereeObj(referee) {
return {
'name': referee.get('name'),
'role': referee.get('role'),
'emailAddress': referee.get('emailAddress'),
'phoneNumber': referee.get('phoneNumber'),
'linkedInUrl': referee.get('linkedInUrl')
};
}
function sectionObj(section) {
return {
'type': section.get('sectionType').get("type"), // *MJ Added the pointer for SectionType > type
'order': section.get('order'),
'content': section.get('content'),
'files': section.get('files').map(fileObj)
};
}
function fileObj(file) {
return {
'name': file.get('name'), // *MJ chnaged the name to be more appropriate
'url': file.get('url'), // *MJ Added the missing comma
'type': file.get('fileType').get("type") //*MJ Added the pointer for fileType > type and removed semi colon
};
}
// *********************************
// ***** fin: mapper functions *****
// *********************************
});
旧
//Return a single project
Parse.Cloud.define('getProject', function(request, response) {
var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
var query = new Parse.Query(Projects);
query.equalTo('projectUrl', request.params.projectUrl);
query.find().then(function(projectsResult) {
var project = projectsResult[0];
var projectData = {
'id': project.id,
'title': project.get('title'),
'previewImage': project.get('previewImage'),
'longDescription': project.get('longDescription'),
'shortDescription': project.get('shortDescription'),
'visibleToPublic': project.get('visibleToPublic'),
'dateStart': project.get('dateStart'),
'dateEnd': project.get('dateEnd'),
'updatedAt': project.get('updatedAt')
};
//Now make the tags query and the referees query in parallel.
var tagsPromise = project.relation('tags').query().find();
var refereesPromise = project.relation('referees').query().find();
var sectionsPromise = project.relation('sections').query().find();
var sectionTypesPromise = project.relation('sections').query().find().relation('type').query().find();
var filesPromise = project.relation('sections').query().find().relation('files').query().find();
var fileTypesPromise = project.relation('sections').query().find().relation('files').query().find().relation('type').query().find();
// Aggregate the two promises with Parse.Promise.when(), and handle the responses.
return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise, sectionTypesPromise, filesPromise, fileTypesPromise).then(function(tags, referees, sections, sectionTypes, files, fileTypes) {
//Process the tags response
projectData.tags = tags.map(function(tag) {
return {
'tag': tag.get('tag')
};
});
//Process the referees response
projectData.referees = referees.map(function(refereee) {
return {
'name': refereee.get('name'),
'role': refereee.get('role'),
'emailAddress': refereee.get('emailAddress'),
'phoneNumber': refereee.get('phoneNumber'),
'linkedInUrl': refereee.get('linkedInUrl')
};
});
//Process the sections response
projectData.sections = sections.map(function(section) {
return {
'order': section.get('order'),
'content': section.get('content')
};
});
// Problem: Sections have a relations column (files)
// which I would like to return as a child of sections.
// The files class then has a pointer column (type)
// to another class which contains the a list of
// file types (i.e. Image, Document, etc...)
// The sections structure of projectDate should
// look like:
//
// "sections": [{
// "type": "Section Type"
// "order": "1",
// "content": "This is the Section content",
// "files": [{
// "filename": "Image 1",
// "url": "image-1.png"
// "type": "Image"
// },
// {
// "filename": "Image 2",
// "url": "image-2.png",
// "type": "Image"
// },
// {
// ...
// }]
// },
// {
// ...
// }
// }]
//Process the section type response. This is reliant on sections being retrieved.
projectData.sections.type = sections.map(function(sectionTypes) {
return {
'type': sectionTypes.get('type')
};
});
//Process the section files response. This is reliant on sections being retrieved.
projectData.sections.files = sections.map(function(files) {
return {
'filename': files.get('filename'),
'url': files.get('url')
};
});
//Process the section files types response. This is reliant on files being retrieved.
projectData.sections.files.type = sections.map(function(fileTypes) {
return {
'type': fileTypes.get('type')
};
});
// Currently not so Yay!
response.success(projectData);
});
}).fail(function(error) {
response.error('Error: ' + error);
});
});
答案 0 :(得分:1)
深入一个级别稍微复杂一点。每个级别都需要一个与顶级模式非常相似的模式。
不幸的是,这些模式自然不适合“平坦”。不断回顾早期结果的需要使得嵌套具有吸引力,尽管可能并非绝对必要;我确定存在其他方法。
这是对代码的尝试。由于无法对其进行测试,因此可能存在错误。
//Return a single project
Parse.Cloud.define('getProject', function(request, response) {
var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
var query = new Parse.Query(Projects);
query.equalTo('projectUrl', request.params.projectUrl);
query.find().then(function(projectsResult) {
var project = projectsResult[0];
//From here, `project` is hierarchically monkey-patched with the results of further queries.
//Make tags query, the referees query and the sections query in parallel.
var tagsPromise = project.relation('tags').query().find();
var refereesPromise = project.relation('referees').query().find();
var sectionsPromise = project.relation('sections').query().find();
// Aggregate the three promises with Parse.Promise.when(), and handle the responses.
return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise).then(function(tags, referees, sections) {
project.set('tags', tags);
project.set('referees', referees);
project.set('sections', sections);
//Go deeper into `sections`
var sectionsRelationsPromises = sections.map(function(section) {
var sectionTypesPromise = section.relation('type').query().find();
var filesPromise = section.relation('files').query().find();
return Parse.Promise.when(sectionTypesPromise, filesPromise).then(function(sectionTypes, files) {
section.set('type', sectionTypes[0]);
section.set('files', files);
//And deeper still into each of the section's files to find their types
var filesRelationsPromises = files.map(function(file) {
return file.relation('type').query().find().then(function(fileTypes) {
file.set('type', fileTypes[0]);
});
});
return Parse.Promise.when(filesRelationsPromises);
});
});
return Parse.Promise.when(sectionsRelationsPromises);
}).then(function() {
return project;
});
}).then(function(project) {
// At this point, all the data is gathered in the form of Parse objects in project,
// which now needs to be mapped into a js plain object.
var projectData = projectObj(project);
projectData.tags = project.get('tags').map(tagObj); //Process the tags response
projectData.referees = project.get('referees').map(refereeeObj); //Process the referees response
projectData.sections = project.get('sections', sections).map(sectionObj); //Process the sections response
projectData.sections.each(function(section) {
section.files = section.get('files').map(fileObj);
});
//Yay! (hopfully)
response.success(projectData);
}).fail(function(error) {
response.error('Error: ' + error);
});
// ***********************************
// ***** start: mapper functions *****
// ***********************************
function projectObj(project) {
return = {
'id': project.id,
'title': project.get('title'),
'previewImage': project.get('previewImage'),
'longDescription': project.get('longDescription'),
'shortDescription': project.get('shortDescription'),
'visibleToPublic': project.get('visibleToPublic'),
'dateStart': project.get('dateStart'),
'dateEnd': project.get('dateEnd'),
'updatedAt': project.get('updatedAt')
}
}
function tagObj(tag) {
return {
'tag': tag.get('tag')
};
}
function refereeObj(referee) {
return {
'name': referee.get('name'),
'role': referee.get('role'),
'emailAddress': referee.get('emailAddress'),
'phoneNumber': referee.get('phoneNumber'),
'linkedInUrl': referee.get('linkedInUrl')
};
}
function sectionObj(section) {
return {
'type': section.get('type'),
'order': section.get('order'),
'content': section.get('content'),
'files': section.get('files').map(fileObj)
};
}
function fileObj(file) {
return {
'filename': file.get('filename'),
'url': file.get('url')
'type': file.get('type');
};
}
// *********************************
// ***** fin: mapper functions *****
// *********************************
});
我已尽可能简化代码:
相信我,这比在一个块中做所有事情更具可读性。我试过了,这是噩梦。
快乐的调试。
答案 1 :(得分:0)
一般地对待这个问题:说你有一个名为" ClassA"它有一个名为" classBs"将它与" ClassB"的许多实例联系起来。而且,也就是说," ClassB"实例有一个名为" classCs"将它们与" ClassC"。
的实例联系起来ClassA --relates to many --< ClassB --relates to many --< ClassC
("classBs") ("classCs")
现在,给定一个&#34; ClassA&#34;的单个实例,如何获取所有&#34; ClassC&#34;通过&#34; ClassB&#34;?
与之相关的实例答案是直截了当的,记住了一些事情:(1)在这里完成拼写数据模型,(2)用更小,更简单的承诺返回原语组成更复杂的逻辑(3)使用Parse .Promise.or执行多个查询的并集。
var _ = require("underscore");
// return a promise for many instances of ClassC related to the given aObject
function getCsFromA(aObject) {
var bRelation = aObject.get("classBs");
return bRelation.query().find().then(function(bObjects) {
// gather all of the bObject's relation's queries
var queries = _.map(bObjects, function(bObject) {
return aObject.get("classCs").query();
});
// get the union of many queries
return Parse.Query.or(queries);
});
}
一些实用点:默认情况下,查询限制为100,并且您可以将限制更改为1000.最多,一千个关系的千位关系是一百万个结果。这肯定会违反parse.com上的一些资源限制。