npm i @x-query-adapter/mongo
See : https://github.com/x-query/x-query
- Schema
const OrderSchema = new Schema({
shop_id: { type: Number },
id: { type: Number },
customer: {
id: { type: Number },
name: { type: String },
phone: { type: String },
},
line_items: [{
id: { type: Number },
barcode: { type: String },
quantity: { type: Number },
type: { type: String },
vendor: { type: String },
price: { type: Number }
}],
total_prices: { type: Number },
created_at: { type: Date },
updated_at: { type: Date },
status: { type: String },
order_number: { type: String },
location_id: { type: Number },
fulfillment_status: { type: String },
is_deleted: { type: Boolean },
tags: [String]
});
- Adapter
const { XQueryMongoAdapter } = require('@x-query-adapter/mongo');
const xQueryAdapter = new XQueryMongoAdapter({
schema: OrderSchema,
required_keys: ['shop_id'],
maxLimit: 1000,
defaults: {
page: 1,
limit: 20,
sort: 'created_at_asc',
is_deleted: false
},
skippedValues: ['', null, undefined],
alias: {
barcode: 'line_items.barcode'
},
});
let query = {
'shop_id' : '100000001',
'created_at_gte' : '2019-04-01T03:15:00.000Z',
'created_at_lte' : '2019-04-30T03:15:00.000Z',
'customer.name_like' : 'hoang',
'barcode' : 'HEO',
'status_in' : 'NEW,ASSIGN_EMPLOYEE',
'page' : '2',
'limit' : '20',
'sort' : 'created_at_asc,id_desc',
'fields' : 'id,customer,line_items',
};
const parse_query_result = xQueryAdapter.parse(query);
assert.deepEqual(parse_query_result, {
"errors": null,
"filter": {
"is_deleted": { "$eq": false },
"shop_id": { "$eq": 100000001 },
"created_at": {
"$gte": "2019-04-01T03:15:00.000Z",
"$lte": "2019-04-30T03:15:00.000Z"
},
"updated_at": {
"$gte": "2019-03-31T17:00:00.000Z",
"$lte": "2019-04-30T16:59:59.999Z"
},
"customer.name": { "$regex": /hoang/gi },
"line_items.barcode": { "$eq": "HEO" },
"status": { "$in": ["NEW", "ASSIGN_EMPLOYEE"]
}
},
"page": 2,
"skip": 20,
"limit": 20,
"sort": {
"created_at": 1,
"id": -1
},
"fields": {
"id": 1,
"customer": 1,
"line_items": 1,
},
});
const xQueryAdapter = new XQueryMongoAdapter({
schema: OrderSchema,
required_keys: ['shop_id'],
maxLimit: 1000,
defaults: {
page: 1,
limit: 20,
sort: 'created_at_asc',
is_deleted: false
},
skippedValues: ['', null, undefined],
alias: {
barcode: 'line_items.barcode'
},
throwError: true // to throw error
});
async function searchOrders({ query }) {
const { filter, fields, skip, limit, sort } = xQueryAdapter.parse(query);
const result = { total: 0, items: [] };
const total = await OrderModel.count(filter);
if (total > 0) {
result.total = total;
result.items = await OrderModel.find(filter, fields).skip(skip).limit(limit).sort(sort).lean(true);
}
return result;
}