findOne and find functions
When you want to penetrate only one step in the depth of relationships, the best choices are find and findOne functions.
According to Mongo's behavior, only Aggregation can be used to send a left join query to receive relationships. But considering that all relationships are automatically embedded in Lesan, you can use find and findOne along with aggregation to get one level of relationships, i.e. the father along with all the children.
findOne functions
find a user
lets add getUser functions:
const getUserValidator = () => {
return object({
set: object({
userId: objectIdValidation,
}),
get: coreApp.schemas.selectStruct("user", 1),
});
};
const getUser: ActFn = async (body) => {
const {
set: { userId },
get,
} = body.details;
return await users.findOne({
filters: { _id: new ObjectId(userId) },
projection: get,
});
};
coreApp.acts.setAct({
schema: "user",
actName: "getUser",
validator: getUserValidator(),
fn: getUser,
});
findOne functions accept three inputs:
filterswhich is mongodb findOne query operationprojectionwhich is mongodb projection operation- and optional
optionwhich is mongodb findOption
You can also read mongodb findOne section for more information.
executing main → user → getUser:
Add E2E Test
Like before, for adding getUser request to E2E section you should click on the E2E button, like below picture.
Then, in the E2E section and getUser sequence, you should replace the user id that you set capture in own sequence with default user id. default user id in getUser sequence is like below picture.
The replaced user id is like below picture.
find a city or country
Finding a city or country is exactly the same as finding a user.
Pay attention to the following code:
const getCountryValidator = () => {
return object({
set: object({
countryId: objectIdValidation,
}),
get: coreApp.schemas.selectStruct("country", {
citiesByPopulation: 1,
users: 1,
capital: 1,
}),
});
};
const getCountry: ActFn = async (body) => {
const {
set: { countryId },
get,
} = body.details;
return await countries.findOne({
filters: { _id: new ObjectId(countryId) },
projection: get,
});
};
coreApp.acts.setAct({
schema: "country",
actName: "getCountry",
validator: getCountryValidator(),
fn: getCountry,
});
const getCityValidator = () => {
return object({
set: object({
cityId: objectIdValidation,
}),
get: coreApp.schemas.selectStruct("city", { country: 1, lovedByUser: 1 }),
});
};
const getCity: ActFn = async (body) => {
const {
set: { cityId },
get,
} = body.details;
return await cities.findOne({
filters: { _id: new ObjectId(cityId) },
projection: get,
});
};
coreApp.acts.setAct({
schema: "city",
actName: "getCity",
validator: getCityValidator(),
fn: getCity,
});
The only difference here is in the coreApp.schemas.selectStruct function. The second input of this function, instead of a number, is an object of the relationship key with a value of one number, which explicitly specifies how much this act can penetrate in this particular relationship.
executing main → city → getCity:
Add E2E Test
For adding getCity request to E2E test section, you should click on the E2E button, like bottom picture.
Then, in the E2E section and getCity sequence, you should replace the city id that you set capture in own sequence with default city id. default city id in getCity sequence is like below picture.
The replaced city id is like below picture.
executing main → country → getCountry:
You can find full example here and test the findOne method in local computer.
Add E2E Test
Also, for adding getCountry request to E2E test section, you should click on the E2E button, like bottom picture.
Then, in the E2E section and getCountry sequence, you should replace the country id that you set capture in own sequence with default country id. default counry id in getCountry sequence is like below picture.
The replace country id is like below picture.
find functions
find users
lets add getUsers functions:
const getUsersValidator = () => {
return object({
set: object({
page: number(),
limit: number(),
}),
get: coreApp.schemas.selectStruct("user", 1),
});
};
const getUsers: ActFn = async (body) => {
let {
set: { page, limit },
get,
} = body.details;
page = page || 1;
limit = limit || 50;
const skip = limit * (page - 1);
return await users
.find({ projection: get, filters: {} })
.skip(skip)
.limit(limit)
.toArray();
};
coreApp.acts.setAct({
schema: "user",
actName: "getUsers",
validator: getUsersValidator(),
fn: getUsers,
});
find functions accept three inputs:
filterswhich is mongodb filter query operationprojectionwhich is mongodb projection operation- and optional
optionwhich is mongodb findOption
You can also read mongodb find section for more information.
executing main → user → getUsers:
Add E2E Test
For adding getUsers request to E2E test section, you should click on the E2E button, like bottom picture.
Well, in the E2E section you can see the getUsers sequence.
find cities or countries
Finding cities or countries is exactly the same as finding users.
Pay attention to the following code:
const getCountriesValidator = () => {
return object({
set: object({
page: number(),
limit: number(),
}),
get: coreApp.schemas.selectStruct("country", {
citiesByPopulation: 1,
users: 1,
capital: 1,
}),
});
};
const getCountries: ActFn = async (body) => {
let {
set: { page, limit },
get,
} = body.details;
page = page || 1;
limit = limit || 50;
const skip = limit * (page - 1);
return await countries
.find({ projection: get, filters: {} })
.skip(skip)
.limit(limit)
.toArray();
};
coreApp.acts.setAct({
schema: "country",
actName: "getCountries",
validator: getCountriesValidator(),
fn: getCountries,
});
const getCitiesValidator = () => {
return object({
set: object({
page: number(),
limit: number(),
}),
get: coreApp.schemas.selectStruct("city", { country: 1, lovedByUser: 1 }),
});
};
const getCities: ActFn = async (body) => {
let {
set: { page, limit },
get,
} = body.details;
page = page || 1;
limit = limit || 50;
const skip = limit * (page - 1);
return await cities
.find({ projection: get, filters: {} })
.skip(skip)
.limit(limit)
.toArray();
};
coreApp.acts.setAct({
schema: "city",
actName: "getCities",
validator: getCitiesValidator(),
fn: getCities,
});
The only difference here is in the coreApp.schemas.selectStruct function. The second input of this function, instead of a number, is an object of the relationship key with a value of one number, which explicitly specifies how much this act can penetrate in this particular relationship.
executing main → city → getCities:
Add E2E Test
Like before, for adding getCities request to E2E test section, you should click on the E2E button, like bottom picture.
Well, in the E2E section you can see the getCities sequence.
executing main → country → getCountries:
You can find full example here and test the find method in local computer.
Add E2E Test
For adding getCountries request to E2E test section, you should click on the E2E button, like bottom picture.
Well, in the E2E section you can see the getCountries sequence.