-
Notifications
You must be signed in to change notification settings - Fork 82
/
lookup.ts
49 lines (45 loc) · 1.19 KB
/
lookup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { Collection, Options } from "../../core";
import { Iterator } from "../../lazy";
import {
assert,
hashCode,
into,
isString,
RawArray,
RawObject,
resolve,
} from "../../util";
/**
* Performs a left outer join to another collection in the same database to filter in documents from the “joined” collection for processing.
*
* @param collection
* @param expr
* @param opt
*/
export function $lookup(
collection: Iterator,
expr: {
from: string | Collection;
localField: string;
foreignField: string;
as: string;
},
options?: Options
): Iterator {
const joinColl = isString(expr.from)
? options?.collectionResolver(expr.from)
: expr.from;
assert(joinColl instanceof Array, `'from' field must resolve to an array`);
const hash: Record<string, RawArray> = {};
for (const obj of joinColl) {
const k = hashCode(resolve(obj, expr.foreignField), options?.hashFunction);
hash[k] = hash[k] || [];
hash[k].push(obj);
}
return collection.map((obj: RawObject) => {
const k = hashCode(resolve(obj, expr.localField), options?.hashFunction);
const newObj = into({}, obj);
newObj[expr.as] = hash[k] || [];
return newObj;
});
}