Return only the categories which have products (Elasticsearch) - elasticsearch

I have two indexes Categories and Products. A product has only one category.
I am looking for a way to query the Category index and filter out all categories that have no products.
Product
id
name
category
id
name
price
Category
id
name
Any ideas on how I can achieve that?

You can run a terms aggregate on field category.id in Product index. Notice set size of the aggregate (NOT the global size to specify the return hits) a big number.

Related

How toc create relations between category and subcategories

I have categories and subcategories tables
Table catgeories:
id
title
description
Table subcategories:
id
category_id
parent_category_id
Data for categories table:
Data for subcategories table
In my case any category has unlimited child categories. How to make relations Many To Many for models to get all categories and there subcategories?
I suggest you to keep the categories in same table like below
id
parent_id
name
1
0
parent cat
2
1
child cat
In the above table parent_id which has 0 value are the actual parent categories, and which has number are child categories, eg: child cate is child of parent cat, in this way you can implement infinite child categories. But Don't worry we can achieve the relations as you have done, please follow as below
Am Assuming categories and subcategories as model. In categories model write a relation as below
public function childCategories(){
return $this->hasMany('\App\subcategories','parent_category_id','id')
->join('categories','categories.id','=','subcategories.categories')
->select("categories.title",'subcategories.*');
}
After the when you calling the categories call it via with as below, you will get categories with related sub categories
$categories = categories::with('childCategories')->get();
To get the category or, the sub-category, you can use this
$allSubCategory = DB::table('sub_categories')->orderBy('id', 'DESC')
->join('categories', 'sub_categories.category_id', '=', 'categories.id')
->select('sub_categories.*', 'categories.category_name')
->get();
$allCategory = DB::table('categorys')->orderBy('id', 'DESC')
->join('sub_categories', 'categorys.category_id', '=', 'sub_categories.id')
->select('categorys.*', 'sub_categories.sub_category_name')
->get();

Newest items and GROUP By with Eloquent

I have the following prices-table:
shop_id (int)
product_id (int)
price (float)
created (DateTime)
Every hour a cronjob checks the shops and inserts new entries (current prices) into these price-table.
Now I want to display the newest price for a product. I have to GROUP BY the shop_id because I only want one price per shop but I only want the newest entry (created).
Can I solve this with Eloquent Query-Builder or do I have to use raw SQL? Is it possible to pass the result of a raw SQL-query into a model if the columns are the same?
You can try it as:
Price::select('*', DB::raw('MAX(created_at) as max_created_at'))
->groupBy('shop_id')
->get()
Assuming model name is Price
Eloquent (purist) approach:
Price::orderBy('created', 'desc')->groupBy('shop_id')
->get('shop_id', 'price');
References:
https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_orderBy
https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_groupBy
https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_get
*untested though
Q: Is it possible to pass the result of a raw SQL-query into a model if the columns are the same?
A: you could pass it to Model's contructor - but it might need model's field to be fillable - or hydrate a model. Alternatively, just access it like an keyed-array, ie. $something[0]['price'] <-- assuming an array of prices with price column.
I solved the problem without QueryBuilder. Instead I use a raw SQL-statement and generating the models with the hydrateRaw()-function of the Model-class.
$prices = Price::hydrateRaw( 'SELECT p.*
FROM prices p
INNER JOIN (
SELECT shop_id, max(created_at) AS max_ca
FROM prices p1
GROUP BY shop_id
) m ON p.shop_id = m.shop_id AND p.created_at = m.max_ca');

Magento - how are categories joined to stores, and to each other

we are using Magento with multiple stores. Each store has categories starting with a root category. I understand that the store is a core_store entity, and category is a catalog_category_entity record, and that they are joined somehow in the EAV attributes table. But I have a few questions on this:
Category C is a subcategory of B is a subcategory of A, i.e. A > B > C - how are the relationships between A and B, and B and C stored?
How is the store joined in? Is there a join table, or is there a column allowing for the category to be listed in a table multiple times, each with a different value for the store field?
You can easily look at the tables and figure this out yourself.
In catalog_category_entity, the subcategories are linked to parent by the parent_id column. This column is also in the flat tables.
If you look in catalog_category_entity_varchar for the category name attribute for example, there's a store_id column. 0 is the default value, 1 is for store view 1, etc. All this means is that on the front end, if say Store View 1 is showing, then the value for the category name is the row in the table with store_id 1. For example, if your category name is "Hello" in Store View 1 English, then it might be "Hola" in Store View 2 Spanish, and so on.

Group join in linq but only where childs is present

I have this simple query and I want to have a list of categories and for each category the number of products inside.
from category in categories
join product in products
on category.Id equals product.Category_Id into productsPerCategories
select new Categories
{
Category = category,
products = productsPerCategories.Count()
};
But if there is no products, I don't want the category to appear. With my current construct, there will be categories with no products inside. How can I achieve that?
Just add a condition
where productsPerCategories.Any()
or
where productsPerCategories.Count() > 0
So your query would be:
from category in categories
join product in products on category.Id equals product.Category_Id into productsPerCategories
where productsPerCategories.Any()
select new Categories
{
Category = category,
products = productsPerCategories.Count()
};

Magento The Amount of times a product has been ordered

I want to show the products that have been purchased the most
so far i am using
$_productCollection = Mage::getResourceModel('reports/product_collection')
->addAttributeToSelect('*')
->addOrderedQty()
->addAttributeToFilter('visibility', $visibility)
->setOrder('ordered_qty', 'desc');
BUT I want to count the amount of time the product has been purchased, disregarding the qty purchased. EG
a customer buys 20 X PRODUCT A (Count this as 1)
a customer buys 1 X PRODUCT B (Count this as 1)
This is because some products are bought in huge quantities so bestsellers data doesn't really reflect our most popular products.
Is this data available?
Cheers
If you have the access of MySQL database then you can easily get the list by query
SELECT sku, count(*)as qty FROM sales_flat_order_item
GROUP BY sku
ORDER BY qty desc
or you can also use Magento Resource Model to get the same
$query = Mage::getResourceModel('sales/order_item_collection');
$query->getSelect()->reset(Zend_Db_Select::COLUMNS)
->columns(array('sku','COUNT(*)'))
->group(array('sku'));

Resources