I'm new to realm. I have a schema like the following:
class MealItem {}
MealItem.schema = {
name: 'MealItem',
properties: {
mealId: {type: 'int'},
foodId: {type: 'int'},
},
};
I want to do the equivalent of :
SELECT
mealId
FROM MealItem
WHERE foodId = #food1
AND mealId IN (SELECT mealId FROM MealItem WHERE foodId = #food2
AND mealId IN (SELECT mealId FROM MealItem WHERE foodId = #food3))
I'm not sure where to begin other than to write A LOT of javascript for loops. Is there a less verbose way to do it?
more info
Basically I have two other objects like this:
class Meal {}
Meal.schema = {
name: 'Meal',
properties: {
mealId: {type: 'int'},
mealName: {type: 'string'},
},
};
class Food{}
Food.schema = {
name: 'Food',
properties: {
foodId: {type: 'int'},
foodName: {type: 'string'},
},
};
So my original query is meant to determine if given 3 different foods, does my restaurant offer a meal / combo for it.
For example, if you set food1 to Big Mac, food2 to Fries, food3 to Soft Drink, you should get a meal back called Big Mac Meal.
If you set food1 to Durian, food2 to Hot Pockets, food3 to Krusty Brand Imitation Gruel, no meal id will return, because my restaurant doesn't serve combo like that.
I don't know much about SQL but what I understand from your question is that you are trying to find meals that contains specific foods.
Realm queries and models works like a NoSQL database so you might need to think a little different while creating your models.
For example, lets say you have 3 tables. One contains Meals, one contains foods and one contains data about which MealId contains which FoodId. In Realm you don't need the 3 table. You can think as its a javascript object.
Example
const meal = {
mealId: 0001,
name: 'Big Fat Menu',
price: '4.99'
foods: [{
foodId: 11,
name: 'Burger'
}, {
foodId: 12,
name: 'Fries'
}, {
foodId: 13,
name: 'Coke'
}]
}
This javascript object can be modeled with Realm like this
const FoodSchema = {
name: 'Food',
primaryKey: 'foodId',
properties: {
foodId: 'string'
name: 'string',
}
};
const MealsSchema = {
name: 'Meal',
primaryKey: 'mealId',
properties: {
mealId: 'string'
name: 'string',
price: 'double',
foods: { type: 'list', , objectType: 'Food'}
}
};
With this schema you can make following query to get a meal that contains a specific food,
const meals = realm..objects('Meal').filtered(`foods.id == ${foodId}`)
This is just a small example to help you out a bit. Hope it helps.
Related
This is currently what my entities look like:
Category Entity
#Entity('category')
export class Category extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
id: string;
#Column({ type: 'text', unique: true })
name: string;
#Column({ type: "text", unique: true })
#Index()
slug: string;
#ManyToMany(() => Listing, (listing) => listing.categories, { cascade: true, onDelete: 'CASCADE' })
listings?: Listing[];
}
Listing Entity
#Entity('listing')
export class Listing extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
id: string;
#ManyToMany(() => Category, (category) => category.listings)
#JoinTable()
categories: Category[];
}
Query 1 (what I'm currently using)
And this is currently what my query looks like:
const listings = await connection.getRepository()
.createQueryBuilder('listing')
.distinct(true)
.leftJoinAndSelect('listing.categories', 'category', 'category.slug IN (:...slugs)', {slugs: [ 'mens-shirts', 'clearance' ]})
.getMany()
Query 1 Result
[] // an empty list of Listings (Type: Listing[])
Query 2 (checking to see if the innerJoinAndSelect was working properly)
const listings = await connection.getRepository()
.createQueryBuilder('listing')
.distinct(true)
.innerJoinAndSelect('listing.categories', 'category')
.getMany();
Query 2 Result
[
Listing {
id: 'c24ea98d-da53-4f14-8706-a3597f3ee4d1',
categories: [ [Category], [Category] ]
},
Listing {
id: 'e8b3e680-85b6-4701-9ad7-bf65de348e76',
categories: [ [Category], [Category] ]
},
Listing {
id: '1bb04ea0-8435-44d6-856f-8eb53f24e941',
categories: [ [Category], [Category] ]
},
Listing {
id: '0735142d-fd38-4fad-b5a7-0356373dd0a3',
categories: [ [Category], [Category] ]
},
]
The innerJoinAndSelect method is working and giving me the results back, and I know why I'm getting an empty array when using the first query. It's because I'm trying to find the field slug on the Array of Categories, instead of each Category in the Array.
Question:
How would I search for the slug names [ 'mens-shirts', 'clearance' ], in the array of Categories (Type: Category[]), using TypeORM's QueryBuilder? Or How could I check to see if each Category in the Categories field, has a slug, that is in [ 'mens-shirts', 'clearance' ]. Is it possible?
You need to use = ANY() when searching if an element is inside an array. So change 'category.slug IN (:...slugs)' to 'category.slug = ANY(:slugs)' (notice how you don't need to use "spread" inside ANY, just reference the array directly)
I want to get nested ref's value within the query I'm executing, but by default response is returning the ref of other collection. consider this minimum example; here are user and coin models, within "users" and "coins" collections
user { // ref: 123456
name: foo
location: bar
}
coin { // ref: 124457
amount: 5457
awardedTo: Ref(Collection("users"), "123456")
}
when I run this query
q.Get(q.Ref(q.Collection("coins"), "124457"))
the response is something like this:
{
data: {
amount: 5457,
awardedTo: #ref: {id: "123456", collection: {…}}
},
ref: #ref: {id: "124457", collection: {…}},
ts: 1622547855525255
}
But how is it possible to get nested user's value in the same query to have a response like this:
{
data: {
amount: 5457,
awardedTo: {
name: foo,
location: bar
}
},
ref: #ref: {id: "124457", collection: {…}},
ts: 1622547855525255
}
I have read Join's documentation but it wasn't helpful in this case, and also tried this way, but it didn't work either:
q.Let({
coin: q.Get(q.Ref(q.Collection("coins"), '124457'))
},
q.Union(
q.Get(q.Select(["data","awaredTo"], q.Var("coin"))),
q.Var("coins")
)
)
you can use this FQL:
Let(
{
coin: Select(['data'],Get(Ref(Collection("coin"), "1"))),
user: Select(['data'],Get(Select(['awardedTo'],Var('coin'))))
},
Merge(Var('coin'),{awardedTo:Var('user')})
)
It retrieves data from coin, extracts the user ref and merge all together.
Luigi
I have a list of movies that could be shown more than once. I decided to provide a user with an option to select multiple dates for a single movie (sanity studio interface).
The schema for movies is as follows:
export default {
name: 'movie',
title: 'Movie',
type: 'document',
fields: [
{
name: 'title',
title: 'Title',
type: 'string'
},
{
name: 'dates',
title: 'Dates',
type: 'array',
of: [
{
type: 'datetime',
options: {
dateFormat: 'YYYY-MM-DD',
timeFormat: 'HH:mm',
timeStep: 15,
calendarTodayLabel: 'Today'
}
}
]
},
{
name: 'poster',
title: 'Poster',
type: 'image',
options: {
hotspot: true
}
},
{
name: 'body',
title: 'Body',
type: 'blockContent'
}
],
preview: {
select: {
title: 'title',
date: 'date',
media: 'poster'
}
}
}
Current query:
const query = groq`*[_type == "movie"]{
title,
dates,
poster,
body
}`
I need to filter the movie that has today's date in the dates array with GROQ
Maybe I'm overcomplicating this and someone will come up with a better way.
The idea is to avoid duplicates in the database (1 movie can be shown 3-6 times). That's the only reason I used an array
The solution for this should be:
const query = '*[_type == "movie" && dates match $today]{title, dates, poster, body}'
const today = new Date().toISOString().split('T')[0]
client.fetch(query, {today}).then(result => {
// movies which are showing today
})
However, there is currently a bug in the string tokenizer which cripples date string matching. In the meantime, I'm afraid your only option is to fetch all movies and filter client side. We're hoping to get this fixed as soon as possible.
I am trying to implement nested categories for Post model.
What I have:
Post.add({
title: { type: String, required: true },
state: { type: Types.Select, options: 'draft, published, archived', default: 'draft', index: true },
author: { type: Types.Relationship, ref: 'User', index: true },
publishedDate: { type: Types.Date, index: true, dependsOn: { state: 'published' } },
content: {
extended: { type: Types.Html, wysiwyg: true, height: 300 },
},
categories: { type: Types.Relationship, ref: 'PostCategory', index: true }
});
And category
PostCategory.add({
name: { type: String, required: true },
subCategories: { type: Types.TextArray }
});
Now I can add a list of subcategories to each category.
What I can't do is to display subcategories while creating a post. Also if I change category I need to load sub categories related to selected category.
My plan was to achieve that with watch functionality but it seems only works on save.
Another thing I was thinking about was to add subcategories as relationship, see ref:
categories: { type: Types.Relationship, ref: 'PostCategory.subCategories', index: true }
But it isn't working as well.
So, if anybody has any ideas how to achieve that, please share.
Thanks.
P.S. Don't hesitate to ask any additional information.
I created nested categories by creating a new model 'PostSubCategory' that allows the user to assign the parent category to the child category when they create the child category:
var keystone = require('keystone');
var Types = keystone.Field.Types;
/**
* PostSubCategory Model
* ==================
*/
var PostSubCategory = new keystone.List('PostSubCategory', {
autokey: { from: 'name', path: 'key', unique: true },
});
PostSubCategory.add({
name: {
type: String,
required: true
},
parentCategory: {
type: Types.Relationship,
ref: 'PostCategory',
required: true,
initial: true
}
});
PostSubCategory.relationship({ ref: 'Post', path: 'subcategories' });
PostSubCategory.register();
Then in my Post.js, I add a field to choose a subcategory with a filter on that field to only select from subcategories that are children of the parent category selected:
subcategory: {
type: Types.Relationship,
ref: 'PostSubCategory',
many: false,
filters: { parentCategory: ':categories' }
}
I'm not sure how well this would work for deeper nesting, and I do have an issue in the edit Post admin ui where changing the parent category for a post doesn't update the available subcategories to choose from until you save and refresh. But it got me far enough along for getting parent/child categories to work.
I want to easily query such results:
[{
name: 'john_doe',
info: {
age: 24,
notes: 'custom text',
phoneNumbers: {
home: 112345678,
work: 1234567,
},
},
}, {...}, {...}...]
... by such query:
contacts.filtered("info.age = 24 AND info.notes CONTAINS 'custom'");
How should i create such schema? docs are very confusing about data types and nested properties:
https://realm.io/docs/react-native/0.14.0/api/Realm.html#~PropertyType
https://realm.io/docs/react-native/latest/#nested-objects
I do not need to retrieve any parts of this data separately - only complete object with all nested objects at once.
You could put all fields into a single object:
var ContactSchema = {
name: 'Contact',
properties: {
name: 'string',
age: 'int',
notes: 'string',
homePhone: 'string',
workPhone: 'string'
}
};
Alternatively you could create child objects for info and phoneNumbers but if you are not sharing this data across multiple contacts then this probably isn't needed.