Lighouse #paginator with all records - graph

I am using #paginator directive on my query and my client wants to get all records of posts from the query. This is my code:
posts: [Post!]! #paginate
I tested this querys:
posts(first:0) {id} #works but don't get all records
posts(first:-1) {id} #error
One way was to get all records was to use the value of total inside the paginatorInfo and make a new query with that value on the first:.
posts(first:0) {
paginatorInfo {
total
}
}
For optimization making 2 querys to get all records is very bad.

The best approach I got was to make a new query (now having two querys for posts with different directives and names) like:
allPosts: [Post!]! #all
Other approaches but not so clean:
Set pagination.max_count to null in the config/lighthouse.php and do (first: 100000000) (the int is 32 bits so has a limit).
Change the #paginantor to a #field(resolver:) and do pagination with pure php.

Related

Create a perl hash from a db select

Having some trouble understanding how to create a Perl hash from a DB select statement.
$sth=$dbh->prepare(qq{select authorid,titleid,title,pubyear from books});
$sth->execute() or die DBI->errstr;
while(#records=$sth->fetchrow_array()) {
%Books = (%Books,AuthorID=> $records[0]);
%Books = (%Books,TitleID=> $records[1]);
%Books = (%Books,Title=> $records[2]);
%Books = (%Books,PubYear=> $records[3]);
print qq{$records[0]\n}
print qq{\t$records[1]\n};
print qq{\t$records[2]\n};
print qq{\t$records[3]\n};
}
$sth->finish();
while(($key,$value) = each(%Books)) {
print qq{$key --> $value\n};
}
The print statements work in the first while loop, but I only get the last result in the second key,value loop.
What am I doing wrong here. I'm sure it's something simple. Many thanks.
OP needs better specify the question and do some reading on DBI module.
DBI module has a call for fetchall_hashref perhaps OP could put it to some use.
In the shown code an assignment of a record to a hash with the same keys overwrites the previous one, row after row, and the last one remains. Instead, they should be accumulated in a suitable data structure.
Since there are a fair number of rows (351 we are told) one option is a top-level array, with hashrefs for each book
my #all_books;
while (my #records = $sth->fetchrow_array()) {
my %book;
#book{qw(AuthorID TitleID Title PubYear)} = #records;
push #all_books, \%book;
}
Now we have an array of books, each indexed by the four parameters.
This uses a hash slice to assign multiple key-value pairs to a hash.
Another option is a top-level hash with keys for the four book-related parameters, each having for a value an arrayref with entries from all records
my %books;
while (my #records = $sth->fetchrow_array()) {
push #{$books{AuthorID}}, $records[0];
push #{$books{TitleID}}, $records[1];
...
}
Now one can go through authors/titles/etc, and readily recover the other parameters for each.
Adding some checks is always a good idea when reading from a database.

Why there is a difference between Alfresco Node Browser and programmatical same query execution?

I have the following query
(TYPE:"ecmcndintregst:nd_int_reg_standards" OR TYPE:"ecmcndcountryst:nd_country_standards") AND (=ecmcnddoc:doc_name_ru:"" OR =ecmcnddoc:doc_name_ru:"\-") AND (=ecmcnddoc:doc_kind_cp_ecmcdict_value:"standard_itu")
and it has different results in Alfresco NodeBrowser (fts-alfresco) and in Java code "solr-fts-alfresco" (both results should be < 1000 and they are)
SearchParameters searchParameters = new SearchParameters();
searchParameters.setLanguage(SearchService.LANGUAGE_SOLR_FTS_ALFRESCO);
searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
searchParameters.setLimitBy(LimitBy.UNLIMITED);
searchParameters.setLimit(1000);
searchParameters.setPermissionEvaluation(PermissionEvaluationMode.EAGER);
searchParameters.addLocale(new Locale("ru", "RU"));
searchParameters.setQuery(query);
tempResultSet = customSearchService.query(searchParameters);
Also, in the Java code the clause =ecmcnddoc:doc_name_ru:""may fails two different ways: as always FALSE in query:
(TYPE:"ecmcndintregst:nd_int_reg_standards" OR TYPE:"ecmcndcountryst:nd_country_standards") AND (=ecmcnddoc:doc_name_ru:"" OR =ecmcnddoc:doc_name_ru:"\-") AND (=ecmcnddoc:doc_kind_cp_ecmcdict_value:"standard_itu")
And always TRUE in query:
(TYPE:"ecmcndintregst:nd_int_reg_standards" OR TYPE:"ecmcndcountryst:nd_country_standards") AND (=ecmcnddoc:doc_name_ru:"") AND (=ecmcnddoc:doc_kind_cp_ecmcdict_value:"standard_itu")
Could you tell me the proper way to use =ecmcnddoc:doc_name_ru:"" clause?
Thank you!
Assuming you're looking for results that have an empty "doc_name_ru", have you tried:
-EXISTS:"ecmcnddoc:doc_name_ru"

Form Running Totals, Ax 2009

Is there an example anywhere of a form that performs running totals in a column located within a grid. The user ordering and filtering of the grid would affect the running totals column.
I can easily perform the above if it was ordering only by transaction date, but including the user ordering and filtering I presume that we would have to use the datasource range() and rangecount() functions (see SysQuery::mergeRanges() for an example) then iterate over these to apply the filtering, then include the dynalinks. The same for the ordering, albeit this is now more complicated.
Any suggestions appreciated. Any appreciations suggested (as in: vote the question up!).
You could implement it as a form datasource display method using this strategy:
Copy the form's datasource query (no need for SysQuery::mergeRanges):
QueryRun qr = new QueryRun(ledgerTrans_qr.query());
Iterate and sum over your records using qr, stop after the current record:
while (qr.next())
{
lt = qr.getNo(1);
total += lt.AmountMST;
if (lt.RecId == _lt.RecId)
break;
}
This could be made more performant if the sorting order was fixed (using sum(AmountMST) and adding a where constraint).
Return the total
This is of cause very inefficient (subquadratic time, O(n^2)).
Caching the results (in a map) may make it usable if there are not too many records.
Update: a working example.
Any observations or criticisms to the code below most welcome. Jan's observation about the method being slow is still valid. As you can see, it's a modification of his original answer.
//BP Deviation Documented
display AmountMST XXX_runningBalanceMST(LedgerTrans _trans)
{
LedgerTrans localLedgerTrans;
AmountMST amountMST;
;
localLedgerTrans = this.getFirst();
while (localLedgerTrans)
{
amountMST += localLedgerTrans.AmountMST;
if (localLedgerTrans.RecId == _trans.RecId)
{
break;
}
localLedgerTrans = this.getNext();
}
return amountMST;
}

CouchDB View with 2 Keys

I am looking for a general solution to a problem with couchdb views.
For example, have a view result like this:
{"total_rows":4,"offset":0,"rows":[
{"id":"1","key":["imported","1"],"value":null},
{"id":"2","key":["imported","2"],"value":null},
{"id":"3","key":["imported","3"],"value":null},
{"id":"4","key":["mapped","4"],"value":null},
{"id":"5,"key":["mapped","5"],"value":null}
]
1) If I want to select only "imported" documents I would use this:
view?startkey=["imported"]&endkey=["imported",{}]
2) If I want to select all imported documents with an higher id then 2:
view?startkey=["imported",2]&endkey=["imported",{}]
3) If I want to select all imported documents with an id between 2 and 4:
view?startkey=["imported",2]&endkey=["imported",4]
My Questtion is: How can I select all Rows with an id between 2 and 4?
You can try to extend the solution above, but prepend keys with a kind of "emit index" flag like this:
map: function (doc) {
emit ([0, doc.number, doc.category]); // direct order
emit ([1, doc.category, doc.number]); // reverse order
}
so you will be able to request them with
view?startkey=[0, 2]&endkey=[0, 4, {}]
or
view?startkey=[1, 'imported', 2]&endkey=[1, 'imported', 4]
But 2 different views will be better anyway.
I ran into the same problem a little while ago so I'll explain my solution. Inside of any map function you can have multiple emit() calls. A map function in your case might look like:
function(doc) {
emit([doc.number, doc.category], null);
emit([doc.category, doc.number], null);
}
You can also use ?include_docs=true to get the documents back from any of your queries. Then your query to get back rows 2 to 4 would be
view?startkey=[2]&endkey=[4,{}]
You can view the rules for sorting at CouchDB View Collation

Filter a product collection by two categories in Magento

I'm trying to find products that are in two categories.
I've found an example to get products that are in category1 OR category2.
http://www.alphadigital.cl/blog/lang/en-us/magento-filter-by-multiple-categories.html
I need products that are in category1 AND category2.
The example in the blog is:
class ModuleName_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection{
public function addCategoriesFilter($categories){
$alias = 'cat_index';
$categoryCondition = $this->getConnection()->quoteInto(
$alias.'.product_id=e.entity_id AND '.$alias.'.store_id=? AND ',
$this->getStoreId()
);
$categoryCondition.= $alias.'.category_id IN ('.$categories.')';
$this->getSelect()->joinInner(
array($alias => $this->getTable('catalog/category_product_index')),
$categoryCondition,
array('position'=>'position')
);
$this->_categoryIndexJoined = true;
$this->_joinFields['position'] = array('table'=>$alias, 'field'=>'position' );
return $this;
}
}
When I'm using this filter alone it perform OR query on several categories.
When I combine this filter with prepareProductCollection of Mage_Catalog_Model_Layer
it somehow remove the filter effect.
How can I change the filter to AND and combine it with prepareProductCollection?
Thanks
Thanks
This code will allow you to filter by multiple categories but avoid completely killing performance if you had to perform multiple collection loads:
$iNumberFeaturedItems = 4;
$oCurrentCategory = Mage::registry('current_category');
$oFeaturedCategory = Mage::getModel('catalog/category')->getCollection()
->addAttributeToFilter('name','Featured')
->getFirstItem();
$aFeaturedCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect(array('name', 'price', 'small_image', 'url_key'), 'inner')
->addStoreFilter()
->addCategoryFilter($oFeaturedCategory)
->addCategoryIds();
The first step is to get a collection of products for one category (in this case, a Featured category). Next step is to get the IDs of the products, notice that this does NOT perform a load (ref Mage_Core_Model_Mysql4_Collection_Abstract::getAllIds())
$aFeaturedProdIds = $aFeaturedCollection->getAllIds();
shuffle($aFeaturedProdIds); //randomize the order of the featured products
Then get the IDs for a second category:
$aCurrentCatProdIds = $oCurrentCategory->getProductCollection()->getAllIds();
And intersect the arrays to find product IDs that exist in both categories:
$aMergedProdIds = array_intersect($aFeaturedProdIds,$aCurrentCatProdIds);
For this particular use case, we loop until we have sufficient intersecting products, traversing up the category tree until we find a large enough match (but stopping at root category!):
while(count($aMergedProdIds) < $iNumberFeaturedItems && $oCurrentCategory->getId() != Mage::app()->getStore()->getRootCategoryId()):
$oCurrentCategory = $oCurrentCategory->getParentCategory();
$aParentCatProdIds = $oCurrentCategory->getProductCollection()->getAllIds();
$aMergedProdIds = array_intersect($aFeaturedProdIds,$aParentCatProdIds);
endwhile;
Finally, filter our initial collection by the IDs of the intersecting products, and return.
$aFeaturedItems = $aFeaturedCollection->addIdFilter(array_slice($aMergedProdIds,0,$iNumberFeaturedItems))->getItems();
return $aFeaturedItems;
I am also working on this to no avail, it was available in magento 1.3 using the attribute filter with finset on the category_ids column, however this was moved into the index table from the entity table and now no longer works.
There is one possible solution, but requries an override function which I found here
But this solution is far from ideal.
I think that it will be enough to call addCategoryFilter() twice on your product collection - once for each category. I have not tested it though, so might be wrong.

Resources