I am trying to perform inner join on two vectors in rust but not sure how to achieve this.
In short, I am looking for employees with their department name.
If anybody is familiar with C# LINQ here, then I am trying to achieve something like below in rust.
Considering same model as specified below in model.rs
from e in employees
join d in department
on e.dept_id equals d.dept_id
select new
{
DeptName= d.dept_name,
Name = e.name
};
Here is my rust language code:
models.rs
use bigdecimal::BigDecimal;
use chrono::{NaiveDateTime, Utc};
pub struct Department {
pub dept_id: i32,
pub dept_name: Option<String>,
pub created_on: Option<NaiveDateTime>,
pub created_by: Option<String>,
pub modified_on: Option<NaiveDateTime>,
pub modified_by: Option<String>,
pub is_active: Option<bool>,
}
impl Department {
pub fn get_departments() -> Vec<Department> {
vec![
Department {
dept_id: 101,
dept_name: Option::from("Software".to_string()),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Jadon".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
Department {
dept_id: 102,
dept_name: Option::from("Hr".to_string()),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Jadon".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
Department {
dept_id: 103,
dept_name: Option::from("Hr".to_string()),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Jadon".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
]
}
}
pub struct Employee {
pub employee_id: i32,
pub name: Option<String>,
pub age: Option<i32>,
pub address: Option<String>,
pub email: Option<String>,
pub dept_id: i32,
pub salary: Option<BigDecimal>,
pub created_on: Option<NaiveDateTime>,
pub created_by: Option<String>,
pub modified_on: Option<NaiveDateTime>,
pub modified_by: Option<String>,
pub is_active: Option<bool>,
}
impl Employee {
pub fn get_employees() -> Vec<Employee> {
vec![
Employee {
employee_id: 1001,
name: Option::from("Marten Babel".to_string()),
age: Option::from(25),
address: Option::from("Netherland".to_string()),
email: Option::from("somemail#gmail.com".to_string()),
dept_id: 101,
salary: Option::from(BigDecimal::from(50000.00)),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Tom".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
Employee {
employee_id: 1002,
name: Option::from("Jack Sancho".to_string()),
age: Option::from(22),
address: Option::from("England".to_string()),
email: Option::from("jacksemail#gmail.com".to_string()),
dept_id: 102,
salary: Option::from(BigDecimal::from(80000.00)),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Tom".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
Employee {
employee_id: 1003,
name: Option::from("Phil Foden".to_string()),
age: Option::from(29),
address: Option::from("England".to_string()),
email: Option::from("philsemail#gmail.com".to_string()),
dept_id: 101,
salary: Option::from(BigDecimal::from(80000.00)),
created_on: Option::from(Utc::now().naive_utc()),
created_by: Option::from("Tom".to_string()),
modified_on: None,
modified_by: None,
is_active: Option::from(true),
},
]
}
}
main.rs
fn main() {
let department: Vec<Department> = Department::get_departments();
for dept in department {
println!(
"Dept Id: {} and Dept Name: {}",
dept.dept_id,
dept.dept_name.unwrap_or_default()
);
}
let employee: Vec<Employee> = Employee::get_employees();
for emp in employee {
println!(
"Name is: {} and age is : {}",
emp.name.unwrap_or_default(),
emp.age.unwrap_or_default()
)
}
}
Here "dept_id" will be acting as a foreign key. The code in main.rs is working fine. I am getting departments and employees but how can I perform join on these two vectors.
Note: As of now I am not using diesel orm. Only looking to perform join on these vectors.
Is it possible in rust ?
Thanks
If you just want to get pairs of &str for the names of the departments and the employees, you can use an iterator chain like so:
let department: Vec<Department> = Department::get_departments();
let employee: Vec<Employee> = Employee::get_employees();
let dept_employee_names = department.iter().flat_map(|d| {
let dept_id = d.dept_id;
let dept_name = &d.dept_name;
employee
.iter()
.filter(move |e| e.dept_id == dept_id)
.map(move |e| {
(
dept_name.as_deref().unwrap_or_default(),
e.name.as_deref().unwrap_or_default(),
)
})
});
for (dept, emp) in dept_employee_names {
println!("dept = {}, emp = {}", dept, emp);
}
Note that this has to search through all of the employees for each department, but that is really a limitation of using vectors. You can probably make this more efficient by changing the data structures.
Related
I am running a graphql query to create a person object. The query works fine and the person is created. However I am receiving the following error in the console
react_devtools_backend.js:2842 Missing field 'create_person' while writing result {
"__typename": "PersonResponse",
"error": null,
"person": {
"__typename": "Person",
"hire_date": "2020-10-01",
"name": {
"__typename": "Name",
"first_name": "Joe",
"last_name": "Doe",
"middle_name": ""
},
"person_id": {
"__typename": "PersonId",
"id_": "44df8f7c-d019-410c-89b4-be602f631055"
},
"preferred_name": {
"__typename": "PreferredName",
"first_name": "J",
"last_name": "Dee",
"middle_name": null
}
},
"status": 201
}
This error seems to be saying that my query is missing a field create_person however create_person is not a field it is the name of the query. My first thought was that the message is due to the null fields (even though they are not required). I tried removing these fields from the schema and I still get the error. I am using React Dev Tools chrome extension but still not sure why I get this error.
As requested the gql schema:
const graphqlSchema = buildSchema(`
type Query {
people(person_id: String): [Person]!
emergency_contacts(
person_id: String!
emergency_contact_id: String
): [EmergencyContact]!
person_success: PersonResponse!
person_not_found: PersonResponse!
person_deleted: PersonResponse!
emergency_contact_success: EmergencyContactResponse!
}
scalar Datetime
type PersonId {
id_: String!
}
type Name {
first_name: String!
last_name: String!
middle_name: String
}
input NameInput {
first_name: String!
last_name: String!
middle_name: String
}
input UpdateNameInput {
first_name: String
last_name: String
middle_name: String
}
type ExemptStatus {
code: String!
description: String!
}
type PreferredName {
first_name: String
last_name: String
middle_name: String
}
input PreferredNameInput {
first_name: String
last_name: String
middle_name: String
}
type Relationship {
code: String!
display: String!
description: String!
}
type Address {
line_1: String!
line_2: String!
city: String!
state: String!
zip_code: String!
}
type Person {
person_id: PersonId!
name: Name!
hire_date: Datetime!
preferred_name: PreferredName
contact_info: ContactInfo
exempt_status: ExemptStatus
hired_hours_per_week: Float
hired_hours_per_two_weeks: Float
emergency_contacts: [EmergencyContact]
}
type PersonResponse {
status: Int
error: String
person: Person
}
input PersonInput {
name: NameInput!
hire_date: Datetime!
preferred_name: PreferredNameInput
contact_info: ContactInfoInput
exempt_status_code: String
hired_hours_per_week: Float
hired_hours_per_two_weeks: Float
}
input AddressInput {
line_1: String!
line_2: String!
city: String!
state: String!
zip_code: String!
}
type ContactInfo {
primary_phone: String!
alternate_phone: String
email: String
address: Address
}
input ContactInfoInput {
primary_phone: String!
alternate_phone: String
email: String
address: AddressInput
}
type EmergencyContactId {
id_: String!
}
type EmergencyContact {
emergency_contact_id: EmergencyContactId!
name: Name!
relationship: Relationship!
contact_info: ContactInfo!
}
input EmergencyContactInput {
name: NameInput!
relationship_code: String!
contact_info: ContactInfoInput!
}
input UpdateEmergencyContactInput {
name: NameInput
relationship_code: String
contact_info: ContactInfoInput
}
type EmergencyContactResponse {
status: Int
error: String
person_id: PersonId
emergency_contact: EmergencyContact
}
type Mutation {
create_person(person_input: PersonInput): PersonResponse
update_name(person_id: String!, name_input: UpdateNameInput!): PersonResponse
update_hire_date(person_id: String!, hire_date: Datetime!): PersonResponse
update_preferred_name(
person_id: String!
preferred_name_input: UpdateNameInput!
): PersonResponse
delete_person(person_id: String!): PersonResponse
}
`);
Getting Scanned count but not count of data according to filter
count: null
items: [{id: "bcd75096-7fd9-4e9d-8675-6877f0609ac2", name: "dxfrdhjkhklklkl", description: "dgdxrfg",…},…]
0: {id: "bcd75096-7fd9-4e9d-8675-6877f0609ac2", name: "dxfrdhjkhklklkl", description: "dgdxrfg",…}
1: {id: "52f6ff60-fc07-4631-a1fb-b039f376ff21", name: "ghnfgyhj", description: "gyhkjmuhjolk",…}
2: {id: "f73dfb37-2778-4b87-88c7-e6f9f5b5c931", name: "drftgserty", description: "trse54rte54ty",…}
3: {id: "6df9f5c2-ec06-4e70-b5e2-133cb0d8e958", name: "tygujghukuh", description: "tuyjyuikuolnh",…}
4: {id: "9360a766-ac89-420c-881b-2b3089bcca7f", name: "kl;", description: "vcbghnjmk,l", is_active: true,…}
5: {id: "c0dcbaff-37d4-4e4c-9375-584ff7110d77", name: "dfhgbdcb", description: "dfxvcx", is_active: true,…},...
scannedCount: 100
I have followed these tutorials to get count HOW TO COUNT THE NUMBER OF RESULTS WITH AWS AMPLIFY DYNAMODB AND GRAPHQL
Filter
var body = {
filter: {
is_active: {
eq: true
}
}
}
Query to get list of todos
export const listTodos = /* GraphQL */ `
query ListTodos(
$filter: ModelTodoFilterInput
$limit: Int
$nextToken: String
) {
listTodos(filter: $filter, limit: $limit, nextToken: $nextToken) {
count
items {
id
name
description
is_active
createdAt
updatedAt
}
scannedCount
}
}
`;
GraphQl shema
type Todo #model {
id: ID!
name: String!
description: String!
is_active: Boolean
}
type ModelTodoConnection {
items: [Todo]
scannedCount: Int
count: Int
total: Int
}
And IF I set limit to 5 and it will send back scannedCount 5 if when I have total data in database around 110. I want to count data where is_active: { eq: true }
Check out the package I wrote to solve this issue: https://github.com/multimeric/AmplifyCountDirective.
After following the installation instructions, to solve your issue I would change the schema to this:
type Todo #model #count {
id: ID!
name: String!
description: String!
is_active: Boolean
}
Then you can query the count using a GraphQL query such as:
{
countTodo(filter: {
is_active: {
eq: true
}
})
}
How to add User in this example? I try to use mutation in all ways but doesn't work.
type User {
masterId: Int
name: String
surname: String
address: Address
}
type Address {
street: String
flat: Int
city: String
country: String
}
I try something like this:
type Mutation {
user(
masterId: Int
name: String
surname: String
address: Address
): User
}
and next
mutation {
user(
masterId: 4,
name: "Kevin",
surname: "Key",
address: {
street: "Clark Street",
flat: 19,
city: "Brentwood",
country: "United Kingdom"
}
)
}
I try different versions, but I really can not find a solution
Try this in the playground after creating datamodel in prisma
mutation {
createUser(
data: {
name: "Kevin",
surname: "Key"
address: {
create: {
street: "Clark Street",
flat: 19,
city: "Brentwood",
country: "United Kingdom"
}
}
}
) {
id
name
}
}
Note
You also use connect if address object is already created, for connect just pass the Address id(Primary Key/ObjectId)
Schema:
type TrackUser {
id: ID! #unique
createdAt: DateTime!
user: User #note there is no `!`
}
type User {
id: ID! #unique
name: String! #unique
}
I want to get Alls TrackUser where User is not null. What would be the query?
This would be a possible query:
query c {
trackUsers(where: { NOT: [{ user: null }] }) {
name
}
}
Here you can see how it looks in the Playground. I added a name to Trackuser in the datamodel in order to be able to create it from that side without a user.
this works, but I guess it is just a hack..
query TrackUsersQuery($orderBy: TrackUserOrderByInput!, $where: TrackUserWhereInput, $first: Int, $skip: Int) {
trackUsers(where: $where, orderBy: $orderBy, first: $first, skip: $skip) {
id
createdAt
user {
id
name
}
}
}
variables = {
where: {
user: {
name_contains: ''
}
}
}
UPDATE:
For Prisma2, here you have the possibilities:
For products that have no invoice, you can use the following:
const data = await prisma.product.findMany({
where: {
invoices: {
none: {
id: undefined,
},
},
},
})
And for Invoices that do not have a product associated:
const data = await prisma.invoice.findMany({
where: {
productId: null,
},
})
more details here: https://github.com/prisma/prisma/discussions/3461
Hi I defined rootQuery in Customer schema and then in Product schema I extended query. I wrote resolvers for product schema but then I got following error: Error: Query.products defined in resolvers, but not in schema.
When I move product queries to customer query definition it works.
I dont understand why I'm getting this error. Do I need implement some rootQuery and insert it into typeDefs array and then extend queries in Customer and Product ?
Customer schema
import CustomerPhoto from "./customerPhoto";
const Customer = `
type Customer {
customerID: ID!
firstname: String
lastname: String
phone: String
email: String
CustomerPhoto: CustomerPhoto
}
input CustomerInput {
firstname: String!
lastname: String!
phone: String!
email: String!
}
type Query {
customers(cursor: Int!):[Customer]
customer(id: Int!): Customer
}
type Mutation {
createCustomer(photo: String!, input: CustomerInput): Customer
updateCustomer(customerID: ID!, photo: String, input: CustomerInput): Customer
deleteCustomer(customerID: ID!): Customer
}
`;
export default [Customer, CustomerPhoto];
Product Schema
import ProductPhoto from "./productPhoto";
const Product = `
type Product {
productID: ID!
name: String!
description: String!
pricewithoutdph: Float!
pricewithdph: Float!
barcode: Int!
ProductPhoto: ProductPhoto
}
extend type Query {
products: [Product]
product(productID: ID!): Product
}
`;
export default [Product, ProductPhoto]
Here Im importing both schemas. Is there something missing ?
const schema = makeExecutableSchema({
typeDefs: [...Customer,...Product],
resolvers: merge(CustomerResolvers, ProductResolvers),
logger: {
log: e => {
console.log("schemaError", e);
}
},
resolverValidationOptions: {
requireResolversForNonScalar: true
}
});
Product Resolvers
const ProductResolvers = {
Query: {
products: (_, { cursor }) => {
return models.Product.findAndCountAll({
include: {
model: models.ProductPhoto,
attributes: ["productPhotoID", "photo"],
required: true
},
offset: cursor,
limit: 10,
attributes: ["productID", "name", "description", "pricewithoutdph", "pricewithdph", "barcode"]
}).then(response => {
return response.rows;
});
}
};
export default ProductResolvers;
Customer Resolvers
const CustomerResolvers = {
Query: {
customers: (_, {cursor}) => {
return models.Customer.findAndCountAll({
include: {
model: models.CustomerPhoto,
attributes: ["customerPhotoID", "photo"],
required: true
},
offset: cursor,
limit: 10,
attributes: ["customerID", "firstname", "lastname", "phone", "email"]
}).then(response => {
return response.rows;
});
}
......
}
};