Solr DataImportHandler cache with multiple keys - caching

I'm trying to index data from a database using the Solr DataImportHandler. The database contains products defined by a class and with multiple features with the following relevant tables:
product table contains a PK product_id and a FK class_id
product_feature table contains a PK (product_id & feature_id)
class_feature table contains a PK (class_id & feature_id)
For each product I need to index multiple product_feature and for each of those I need to index multiple class_feature. I also need to cache sub-entities for improved performance. The entity-definitions in the config look like this:
<entity name="product" query="select product_id, class_id, ... from product">
...
<entity name="product_feature" query="select product_id, feature_id, ... from product_feature"
cacheImpl="SortedMapBackedCache" cacheKey="product_id" cacheLookup="product.product_id">
...
<entity name="class_feature" query="select class_id, feature_id, ... from class"
cacheImpl="SortedMapBackedCache" where="class_id=product.class_id AND feature_id=product_feature.feature_id">
...
</entity>
</entity>
</entity>
Notice in the innermost entity class_feature, I'm defining a where attribute matching two FKs, one on the outermost product and another on the direct parent product_feature. This doesn't seem to work. How must I define an entity cache to match on multiple keys?

Related

How to enable solr document cache between 2 independent entities?

Am trying to index an application (which has both metadata and attachments along with it). Am using DIH to build the solr documents. In my DIH Config xml, i have defined 2 separate entities, in which first one will fetch the metadata for all my active records, and the second entity will fetch the attachments(can be 0 to many )for all those records.
Both these entities have a "SEQUENCE ID" in common, Is there a way i can cache the SEQUENCE IDs from my first entity & re use that in second entity?
Appreciate any help
Thanks!
<entity name="metadata" query="SELECT sequence_id,field1,field2 from table1 where active_indicator='Y'">
<field column="sequence_id" name="seq_id"/>
<field column="field1" name="field_1"/>
<field column="field2" name="field_2" />
</entity>
<entity name="attachments" query="select t2.sequence_id,t2.field3 from table1 t1,table2 t2 where t1.sequence_id=t2.sequence_id and t1.sequence_id=(SELECT sequence_id from table1 where active_indicator='Y')">
<!--if i can get the t1.sequence_id cached, i can use them to select attachments for those seq ids alone-->
<field column="sequence_id" name="seq_id"/>
<field column="field3" name="field_3"/>
</entity>
</document>
You can wrap your dependent entities inside the entity it depends on, which will give you access to the column values for the rows in the parent entity. There's an example in the community wiki with multiple entities within each other.
<entity name="record" query="SELECT * FROM records">
<entity name="attachment"
query="SELECT field_1, field_2 FROM attachments WHERE SEQUENCE_ID='${record.SEQUENCE_ID}'">
<field name="attachment_val" column="field_1" />
</entity>
<field ... />
</entity>
This is the basic DIH configuration and should work. To rewrite this to use the cache implementation (if that's what you're asking for), you'll have to configure the inner entity to select all rows and use the cache for lookups:
<entity name="attachment"
query="SELECT field_1, field_2 FROM attachments"
cacheKey="SEQUENCE_ID" cacheLookup="record.SEQUENCE_ID">
....
</entity>
The functionality should otherwise be the same.

Arel query issues using where and group

In Rails 4, I have these 3 tables:
Users table with these columns:
-name
-email
Orders table with these columns:
-amount
-user_id
Items table with these columns:
-name
-description
OrderItems table with these columns:
order_id
item_id
Relations:
-The orderItems table is a joined table
-The user has many orders and an order belongs to a user.
Questions:
1) Find the 5 biggest orders (orders with the most items)
I think the query is:
OrderItem.group(:order_id).order(count(id) desc").limit(5).pluck(:order_id)
What is the group exactly doing? When I type in OrderItem.group(:order_id) only I Don't understand the output.
2) How do I find a user with the name "betty" AND "the email "betty#gmail.com". For this, do I need to write SQL inside my Arel?
OrderItem.group(:order_id) by itself won't produce valid SQL. group turns into an SQL GROUP BY statement which groups rows together if they share the same value for the column that is specified. GROUP BY needs to be used with a SELECT statement that has the columns that were in the GROUP BY or that are aggregate functions like COUNT.
Your full query is missing a quotation mark in the order clause. You'll want:
OrderItem.group(:order_id).order("count(id) desc").limit(5).pluck(:order_id)
To find a user with the name "betty" and the email "betty#gmail.com" you can use:
User.where(name: "betty", email: "betty#gmail.com")

Join tables and display the data in Magento Grid using XML

I am trying to customise Magento Sales/Order/Grid by adding columns to display data for
Customer_Id
Billing_Address
Shipping_Address
I've created a module following an earlier post
I am now trying to join the tables but haven't been able to figure out how to do this using XML.
<gridcontrol>
<grids>
<sales_order_grid>
<!-- remove order id -->
<shipping_address>
<add>
<header>Shipping Address</header>
<!-- join shipping address from sales/order table -->
<join table="sales_flat_order_address" condition="sales_flat_order_address.entity_id={{table}}.street" field="street"/>
</add>
<after>status</after>
</shipping_address>
<billing_address>
<add>
<header>Billing Address</header>
<!-- join shipping address from sales/order table -->
<join table="sales_flat_order_address" condition="sales_flat_order_address.entity_id={{table}}.street" field="street"/>
</add>
<after>status</after>
</billing_address>
<customer_id>
<add>
<header>Customer Id</header>
<!-- join shipping address from sales/order table -->
<join table="sales_flat_order" condition="main_table.cutomer_id={{table}}.customer_id" field="customer_id"/>
</add>
<after>status</after>
</customer_id>
</sales_order_grid>
</grids>
</gridcontrol>
I have the new columns showing in my grid but there are empty so I know I am doing something incorrectly and I assume it is something really simple. I would be grateful if someone could show me how to join the correct tables using this method.
Why dont you try doing , _prepareCollection()
$collection->getSelect()->columns(array('filename' => new Zend_Db_Expr ("(SELECT
filename FROM table_name WHERE customer_id =e.entity_id)")));
$this->setCollection($collection);

Count the number of rows in many to many relationships in Hibernate

I have three of many tables in Oracle (10g) database as listed below. I'm using Hibernate Tools 3.2.1.GA with Spring version 3.0.2.
Product - parent table
Colour - parent table
ProductColour - join table - references colourId and prodId of Colour and Product tables respectively
Where the ProductColour is a join table between Product and Colour. As the table names imply, there is a many-to-many relationship between Product and ProductColour. I think, the relationship in the database can easily be imagined and is clear with only this much information. Therefore, I'm not going to explore this relationship at length.
One entity (row) in Product is associated with any number entities in Colour and one entity (row) in Colour can also be associated with any number of entities in Product.
Let's say as for an example, I need to count the number of rows available in the Product table (regarding Hibernate), it can be done something like the following.
Object rowCount = session.createCriteria(Product.class)
.setProjection(Projections.rowCount()).uniqueResult();
What if I need to count the number of rows available in the ProductColour table? Since, it is a many-to-many relationship, it is mapped in the Product and the Colour entity classes (POJOs) with there respective java.util.Set and no direct POJO class for the ProductColour table is available. So the preceding row-counting statement doesn't seem to work in this scenario.
Is there a precise way to count the number of rows of such a join entity in Hibernate?
I think you should be able to do a JPQL or HQL along the lines.
SELECT count(p.colors) FROM Product AS p WHERE p.name = :name ... other search criteria etc
or
SELECT count(c.products) FROM Color AS c WHERE c.name = :name .... other search criteria
From Comment below, this should work:
Long colours=(Long) session.createQuery("select count(*) as cnt from Colour colour where colour.colourId in(select colours.colourId from Product product inner join product.colours colours where product.prodId=:prodId)").setParameter("prodId", prodId).uniqueResult();

Oracle 11g Text: Composite Domain Index - FILTER BY on columns from different tables

I am using Oracle 11g Text,
AuthorTable : (a table for Author details)
AuthorId, AuthorName, AuthorDOB
ArticleTable : (a table for Article content) ArticleId, WrittenDate, PublishDate, ARTICLE_TXT (CLOB)
LocationTable : (a table for Location) LocationId, LocationState, LocationCity
ArticleAuthorAssocTable: (a table for Article-Author Association) AuthorId, ArticleId
LocAuthorAssocTable: (a table for Author-Location Association) AuthorId, LocationId, LocationStartDate, LocationEndDate
My query need to search for any input search term on ARTICLE_TXT along with any other query on PublishDate / WrittenDate / AuthorDOB / LocationCity / LocationStartDate range.
As I have to do a mixed-query, I started creating Composite Domain Index CDI on ArticleTable.
CREATE INDEX ARTICLE_TXT_CDI_IDX ON ArticleTable(ARTICLE_TXT)
INDEXTYPE IS ctxsys.CONTEXT
FILTER BY WrittenDate, PublishDate
and the query as
SELECT
/*+ domain_index_sort domain_index_filter(ARTICLE_TXT_CDI_IDX) */ article.ARTICLE_TXT,
author.AuthorName , article.WrittenDate, article.PublishDate, LocationTable.LocationCity ,location.LocationStartDate, location.LocationEndDate
FROM
ArticleTable article
INNER JOIN
ArticleAuthorAssocTable articleAuthorAssoc ON article.articleId = articleAuthorAssoc .articleId
INNER JOIN
AuthorTable author ON author.authorId= articleAuthorAssoc.authorId
INNER JOIN
LocAuthorAssocTable locAuthorAssoc req ON author.authorId = locAuthorAssoc.authorId
INNER JOIN
LocationTable location ON location .authorId = locAuthorAssoc.authorId
WHERE
CONTAINS(article.ARTICLE_TXT, 'Something') >0
AND author.AuthorDOB BETWEEN TO_DATE('01/01/2001','MM/DD/YYYY')
AND TO_DATE('12/31/2012','MM/DD/YYYY')
AND location.LocationId IN (1,2)
Now my questions are:
Is it possible to create Composite Domain Index with FILTER BY on
columns from different tables ?
Is there any other way to improve the above query ?
From my research, some options are using materialized view, function-based index, USER_DATASTORE
But unfortunately still not sure how to use them... Please help me with your knowledge.
Thanks
I think the best solution to this problem is to add a XML column to the ArticleTable where you combine all the required info of the article.
Then you need to add triggers to the involved tables to recreate this xml when data changes are happening.
This way you could index this xml column and search for very specific information, using section groups (eg like 'PATH_SECTION_GROUP')

Resources