Skip to content

Commit 49d6e89

Browse files
authored
Merge pull request #5338 from rocketspacer/feature/alias-query
Query and construct document with aliases with Model.translateAliases
2 parents a7530e5 + d8cdb44 commit 49d6e89

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

lib/model.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,42 @@ Model.base;
10571057

10581058
Model.discriminators;
10591059

1060+
/**
1061+
* Translate any aliases fields/conditions so the final query or document object is pure
1062+
*
1063+
* ####Example:
1064+
*
1065+
* Character
1066+
* .find(Character.translateAliases({
1067+
* '名': 'Eddard Stark' // Alias for 'name'
1068+
* })
1069+
* .exec(function(err, characters) {})
1070+
*
1071+
* ####Note:
1072+
* Only translate arguments of object type anything else is returned raw
1073+
*
1074+
* @param {Object} raw fields/conditions that may contain aliased keys
1075+
* @return {Object} the translated 'pure' fields/conditions
1076+
*/
1077+
Model.translateAliases = function translateAliases(fields) {
1078+
var aliases = this.schema.aliases;
1079+
1080+
if (typeof fields === 'object') {
1081+
// Fields is an object (query conditions or document fields)
1082+
for (var key in fields) {
1083+
if (aliases[key]) {
1084+
fields[aliases[key]] = fields[key];
1085+
delete fields[key];
1086+
}
1087+
}
1088+
1089+
return fields;
1090+
} else {
1091+
// Don't know typeof fields
1092+
return fields;
1093+
}
1094+
};
1095+
10601096
/**
10611097
* Removes the first document that matches `conditions` from the collection.
10621098
* To remove all documents that match `conditions`, set the `justOne` option

lib/schema.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ function Schema(obj, options) {
7575

7676
this.obj = obj;
7777
this.paths = {};
78+
this.aliases = {};
7879
this.subpaths = {};
7980
this.virtuals = {};
8081
this.singleNestedPaths = {};
@@ -138,7 +139,6 @@ function Schema(obj, options) {
138139
* Create virtual properties with alias field
139140
*/
140141
function aliasFields(schema) {
141-
// console.log(schema.paths);
142142
for (var path in schema.paths) {
143143
if (!schema.paths[path].options) continue;
144144

@@ -147,6 +147,11 @@ function aliasFields(schema) {
147147

148148
if (alias) {
149149
if ('string' === typeof alias && alias.length > 0) {
150+
if (schema.aliases[alias])
151+
throw new Error('Duplicate alias, alias ' + alias + ' is used more than once');
152+
else
153+
schema.aliases[alias] = prop;
154+
150155
schema
151156
.virtual(alias)
152157
.get((function(p) {

test/model.translateAliases.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Test dependencies.
3+
*/
4+
5+
var start = require('./common'),
6+
assert = require('power-assert'),
7+
mongoose = start.mongoose;
8+
9+
describe('model translate aliases', function() {
10+
it('should translate correctly', function() {
11+
var Character = mongoose.model('Character', new mongoose.Schema({
12+
name: { type: String, alias: '名' },
13+
bio: {
14+
age: { type: Number, alias: '年齢' }
15+
}
16+
}));
17+
18+
assert.deepEqual(
19+
// Translate aliases
20+
Character.translateAliases({
21+
'名': 'Stark',
22+
'年齢': 30
23+
}),
24+
// How translated aliases suppose to look like
25+
{
26+
name: 'Stark',
27+
'bio.age': 30
28+
}
29+
);
30+
});
31+
});

0 commit comments

Comments
 (0)