mirror of
https://github.com/vale981/grapher
synced 2025-03-05 09:31:42 -05:00
Handle deeply nested fields inside links in the query and handle cleaning reducer leftovers for snapCache fields
This commit is contained in:
parent
b49c168fe8
commit
4cdcbea195
7 changed files with 48 additions and 6 deletions
3
lib/query/hypernova/buildAggregatePipeline.js
Normal file → Executable file
3
lib/query/hypernova/buildAggregatePipeline.js
Normal file → Executable file
|
@ -1,4 +1,5 @@
|
|||
import { _ } from 'meteor/underscore';
|
||||
import {SAFE_DOTTED_FIELD_REPLACEMENT} from './constants';
|
||||
|
||||
export default function (childCollectionNode, filters, options, userId) {
|
||||
let containsDottedFields = false;
|
||||
|
@ -31,7 +32,7 @@ export default function (childCollectionNode, filters, options, userId) {
|
|||
if (field.indexOf('.') >= 0) {
|
||||
containsDottedFields = true;
|
||||
}
|
||||
const safeField = field.replace('.', '___');
|
||||
const safeField = field.replace(/\./g, SAFE_DOTTED_FIELD_REPLACEMENT);
|
||||
dataPush[safeField] = '$' + field
|
||||
});
|
||||
|
||||
|
|
2
lib/query/hypernova/lib/snapBackDottedFields.js
Normal file → Executable file
2
lib/query/hypernova/lib/snapBackDottedFields.js
Normal file → Executable file
|
@ -6,7 +6,7 @@ export default function (aggregationResult) {
|
|||
result.data = result.data.map(document => {
|
||||
_.each(document, (value, key) => {
|
||||
if (key.indexOf(SAFE_DOTTED_FIELD_REPLACEMENT) >= 0) {
|
||||
document[key.replace(SAFE_DOTTED_FIELD_REPLACEMENT, '.')] = value;
|
||||
document[key.replace(new RegExp(SAFE_DOTTED_FIELD_REPLACEMENT, 'g'), '.')] = value;
|
||||
delete document[key];
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import dot from 'dot-object';
|
||||
|
||||
/**
|
||||
* @param root
|
||||
*/
|
||||
|
@ -16,7 +18,7 @@ export default function cleanReducerLeftovers(root) {
|
|||
|
||||
_.each(root.fieldNodes, node => {
|
||||
if (node.scheduledForDeletion) {
|
||||
cleanNestedFields(node.name.split('.'), root.results);
|
||||
cleanNestedFields(node.name.split('.'), root.results, root);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -38,8 +40,10 @@ export default function cleanReducerLeftovers(root) {
|
|||
* @param parts
|
||||
* @param results
|
||||
*/
|
||||
function cleanNestedFields(parts, results) {
|
||||
const fieldName = parts[0];
|
||||
function cleanNestedFields(parts, results, root) {
|
||||
const snapCacheField = root.snapCaches[parts[0]];
|
||||
const fieldName = snapCacheField ? snapCacheField : parts[0];
|
||||
|
||||
if (parts.length === 1) {
|
||||
|
||||
results.forEach(result => {
|
||||
|
@ -52,7 +56,7 @@ function cleanNestedFields(parts, results) {
|
|||
}
|
||||
|
||||
parts.shift();
|
||||
cleanNestedFields(parts, results.map(result => result[fieldName]));
|
||||
cleanNestedFields(parts, results.map(result => result[fieldName]), root);
|
||||
|
||||
results.forEach(result => {
|
||||
if (_.isObject(result[fieldName]) && _.keys(result[fieldName]).length === 0) {
|
||||
|
|
|
@ -94,6 +94,10 @@ Authors.addReducers({
|
|||
posts: {
|
||||
authorCached: {
|
||||
name: 1,
|
||||
// this tests cleanReducerLeftovers for snapCache fields
|
||||
profile: {
|
||||
lastName: 1,
|
||||
}
|
||||
},
|
||||
metadata: {
|
||||
keywords: 1
|
||||
|
|
|
@ -55,6 +55,9 @@ _.each(authors, (author) => {
|
|||
title: `User Post - ${idx}`,
|
||||
metadata: {
|
||||
keywords: _.sample(TAGS, _.random(1, 2)),
|
||||
language: {
|
||||
..._.sample([{abbr: 'en', title: 'English'}, {abbr: 'de', title: 'Deutsch'}]),
|
||||
}
|
||||
},
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
|
|
@ -256,6 +256,8 @@ describe('Reducers', function() {
|
|||
*
|
||||
* This necessitates the use of embedReducerWithLink() function while creating reducers,
|
||||
* which was failing for denormalized fields and also for nested fields.
|
||||
*
|
||||
* Also, the commentsReducer2 uses nested item in the body, profile: {lastName: 1}
|
||||
*/
|
||||
const query = createQuery({
|
||||
authors: {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { createQuery } from 'meteor/cultofcoders:grapher';
|
||||
import dot from 'dot-object';
|
||||
import Comments from './bootstrap/comments/collection.js';
|
||||
import './metaFilters.server.test';
|
||||
import './reducers.server.test';
|
||||
|
@ -568,4 +569,31 @@ describe('Hypernova', function() {
|
|||
assert.isArray(user.restaurants);
|
||||
assert.lengthOf(user.restaurants, 1);
|
||||
});
|
||||
|
||||
it('Should fetch deeply nested fields inside links', function() {
|
||||
const query = createQuery({
|
||||
authors: {
|
||||
posts: {
|
||||
metadata: {
|
||||
language: {
|
||||
abbr: 1,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const data = query.fetch();
|
||||
|
||||
assert.isTrue(data.length > 0);
|
||||
|
||||
data.forEach(author => {
|
||||
author.posts.forEach(post => {
|
||||
assert.isObject(post.metadata);
|
||||
assert.isObject(post.metadata.language);
|
||||
assert.isDefined(post.metadata.language.abbr);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue