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:
filters
which is mongodb findOne query operationprojection
which is mongodb projection operation- and optional
option
which 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:
filters
which is mongodb filter query operationprojection
which is mongodb projection operation- and optional
option
which 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.