select支持了randomRange
This commit is contained in:
parent
441e80d7f1
commit
a235dba23f
73
lib/crud.js
73
lib/crud.js
|
|
@ -72,11 +72,39 @@ function pruneAggrResult(schema, entity, result) {
|
|||
}
|
||||
async function select(params, context) {
|
||||
const { entity, selection, option, getCount, maxCount } = params;
|
||||
const data = await context.select(entity, selection, option || {});
|
||||
const { randomRange, count } = selection;
|
||||
let selection2 = selection;
|
||||
if (randomRange) {
|
||||
// 如果是随机取值,这里就从randomRange的ids中随机取
|
||||
const idSelection = Object.assign({}, selection, {
|
||||
indexFrom: 0,
|
||||
count: randomRange,
|
||||
data: {
|
||||
id: 1,
|
||||
},
|
||||
});
|
||||
const ids = await context.select(entity, idSelection, option || {});
|
||||
const possibility = count / ids.length;
|
||||
let reduced = ids.length - count;
|
||||
const ids2 = ids.filter((id) => {
|
||||
const rand = Math.random();
|
||||
if (rand > possibility && reduced) {
|
||||
reduced--;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
selection2.filter = {
|
||||
id: {
|
||||
$in: ids2,
|
||||
},
|
||||
};
|
||||
}
|
||||
const data = await context.select(entity, selection2, option || {});
|
||||
const result = {
|
||||
ids: data.map(ele => ele.id),
|
||||
};
|
||||
if (getCount) {
|
||||
if (getCount && !randomRange) {
|
||||
const { filter } = selection;
|
||||
const count = await context.count(entity, Object.assign({}, { filter, count: maxCount || 1000 }), option || {});
|
||||
Object.assign(result, {
|
||||
|
|
@ -84,49 +112,8 @@ async function select(params, context) {
|
|||
});
|
||||
}
|
||||
if (data.length === 0) {
|
||||
/**
|
||||
* 若selection的projection和filter中同时对某一个外键有限制,此时这条属性路径可能会有关于此对象的权限判定。
|
||||
* 若此时Data为空,则路径上的中间对象不会被返回,会导致前台的权限判定不完整
|
||||
* 如 sku的create权限(jichuang项目), sku.companyService.company上有user relation
|
||||
* 如果sku为空,也应当试着把companyService数据返回给前台
|
||||
* by Xc 20230320
|
||||
*
|
||||
* 感觉已经不需要了,新的权限判定可以判定filter或者data上的cascade路径条件
|
||||
* by Xc 20230519
|
||||
*/
|
||||
/* const { data, filter } = selection;
|
||||
for (const attr in data) {
|
||||
const rel = judgeRelation<ED>(context.getSchema(), entity, attr);
|
||||
if (rel === 2) {
|
||||
const f = filter && getCascadeEntityFilter(filter, attr);
|
||||
if (f) {
|
||||
await context.select(attr, {
|
||||
data: data[attr],
|
||||
filter: f,
|
||||
indexFrom: 0,
|
||||
count: 1, // 取一行应该就够了
|
||||
},
|
||||
option || {})
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string') {
|
||||
const f = filter && getCascadeEntityFilter(filter, attr);
|
||||
if (f) {
|
||||
await context.select(rel, {
|
||||
data: data[attr],
|
||||
filter: f,
|
||||
indexFrom: 0,
|
||||
count: 1, // 取一行应该就够了
|
||||
},
|
||||
option || {})
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* selection的projection中可能有aggr,这个结果前台需要返回
|
||||
*/
|
||||
const aggrData = pruneAggrResult(context.getSchema(), entity, data);
|
||||
if (aggrData) {
|
||||
result.aggr = aggrData;
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import { Context, EntityDict, OperateParams, OperationResult, SelectionResult } from "oak-domain/lib/types";
|
||||
import { AmapInstance } from "oak-external-sdk";
|
||||
export declare type CommonAspectDict<ED extends EntityDict, Cxt extends Context<ED>> = {
|
||||
operate: <T extends keyof ED>(options: {
|
||||
entity: T;
|
||||
operation: ED[T]['Operation'] | ED[T]['Operation'][];
|
||||
params?: OperateParams;
|
||||
}, context: Cxt) => Promise<OperationResult<ED>[] | OperationResult<ED>>;
|
||||
select: <T extends keyof ED, S extends ED[T]['Selection']>(options: {
|
||||
entity: T;
|
||||
selection: ED[T]['Selection'];
|
||||
params?: object;
|
||||
}, context: Cxt) => Promise<SelectionResult<ED[T]['Schema'], S['data']>>;
|
||||
amap: <T extends 'getDrivingPath' | 'regeo' | 'ipLoc' | 'getDistrict' | 'geocode'>(options: {
|
||||
key: string;
|
||||
method: T;
|
||||
data: Parameters<AmapInstance[T]>[0];
|
||||
}) => Promise<any>;
|
||||
getTranslations: (options: {
|
||||
namespace: string | string[];
|
||||
locale: string;
|
||||
}) => Promise<any>;
|
||||
};
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import { OperateParams, EntityDict, Context } from 'oak-domain/lib/types';
|
||||
export declare function operate<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>>(options: {
|
||||
entity: T;
|
||||
operation: ED[T]['Operation'] | ED[T]['Operation'][];
|
||||
params?: OperateParams;
|
||||
}, context: Cxt): Promise<import("oak-domain/lib/types").OperationResult<ED> | Awaited<import("oak-domain/lib/types").OperationResult<ED>>[]>;
|
||||
export declare function select<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, S extends ED[T]['Selection']>(options: {
|
||||
entity: T;
|
||||
selection: S;
|
||||
params?: object;
|
||||
}, context: Cxt): Promise<import("oak-domain/lib/types").SelectionResult<ED[T]["Schema"], S["data"]>>;
|
||||
82
src/crud.ts
82
src/crud.ts
|
|
@ -126,9 +126,46 @@ export async function select<
|
|||
context: Cxt
|
||||
) {
|
||||
const { entity, selection, option, getCount, maxCount } = params;
|
||||
const { randomRange, count } = selection;
|
||||
let selection2 = selection;
|
||||
if (randomRange) {
|
||||
// 如果是随机取值,这里就从randomRange的ids中随机取
|
||||
const idSelection = Object.assign({}, selection, {
|
||||
indexFrom: 0,
|
||||
count: randomRange,
|
||||
data: {
|
||||
id: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const ids = await context.select(
|
||||
entity,
|
||||
idSelection,
|
||||
option || {}
|
||||
);
|
||||
|
||||
const possibility = count! / ids.length;
|
||||
let reduced = ids.length - count!;
|
||||
const ids2 = ids.filter(
|
||||
(id) => {
|
||||
const rand = Math.random();
|
||||
if (rand > possibility && reduced) {
|
||||
reduced --;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
selection2.filter = {
|
||||
id: {
|
||||
$in: ids2,
|
||||
},
|
||||
};
|
||||
}
|
||||
const data = await context.select(
|
||||
entity,
|
||||
selection,
|
||||
selection2,
|
||||
option || {}
|
||||
);
|
||||
const result = {
|
||||
|
|
@ -138,7 +175,7 @@ export async function select<
|
|||
count?: number;
|
||||
aggr?: (Partial<ED[T]['Schema']> | undefined)[];
|
||||
};
|
||||
if (getCount) {
|
||||
if (getCount && !randomRange) {
|
||||
const { filter } = selection;
|
||||
const count = await context.count(
|
||||
entity,
|
||||
|
|
@ -151,49 +188,8 @@ export async function select<
|
|||
}
|
||||
|
||||
if (data.length === 0) {
|
||||
/**
|
||||
* 若selection的projection和filter中同时对某一个外键有限制,此时这条属性路径可能会有关于此对象的权限判定。
|
||||
* 若此时Data为空,则路径上的中间对象不会被返回,会导致前台的权限判定不完整
|
||||
* 如 sku的create权限(jichuang项目), sku.companyService.company上有user relation
|
||||
* 如果sku为空,也应当试着把companyService数据返回给前台
|
||||
* by Xc 20230320
|
||||
*
|
||||
* 感觉已经不需要了,新的权限判定可以判定filter或者data上的cascade路径条件
|
||||
* by Xc 20230519
|
||||
*/
|
||||
/* const { data, filter } = selection;
|
||||
for (const attr in data) {
|
||||
const rel = judgeRelation<ED>(context.getSchema(), entity, attr);
|
||||
if (rel === 2) {
|
||||
const f = filter && getCascadeEntityFilter(filter, attr);
|
||||
if (f) {
|
||||
await context.select(attr, {
|
||||
data: data[attr],
|
||||
filter: f,
|
||||
indexFrom: 0,
|
||||
count: 1, // 取一行应该就够了
|
||||
},
|
||||
option || {})
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string') {
|
||||
const f = filter && getCascadeEntityFilter(filter, attr);
|
||||
if (f) {
|
||||
await context.select(rel, {
|
||||
data: data[attr],
|
||||
filter: f,
|
||||
indexFrom: 0,
|
||||
count: 1, // 取一行应该就够了
|
||||
},
|
||||
option || {})
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* selection的projection中可能有aggr,这个结果前台需要返回
|
||||
*/
|
||||
const aggrData = pruneAggrResult(context.getSchema(), entity, data);
|
||||
if (aggrData) {
|
||||
result.aggr = aggrData;
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
export declare function getTranslations(options: {
|
||||
namespace: string | string[];
|
||||
locale: string;
|
||||
}): Promise<{
|
||||
common: {
|
||||
action: {
|
||||
confirm: string;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
Loading…
Reference in New Issue