コレクションのgetsize()とcount()の違い
-
16-10-2019 - |
質問
どちらも同じだと聞いたことがあります。しかし、私は奇妙な問題に直面しています。CatalogSearchモジュールの製品コレクションでは、count()が正しい製品数を返している間、GetSize()がゼロを返しています。
だから、基本的にこれは私が得ているものです:
$collection->count(); //correct count
$collection->getSize(); //0
しかし、検索ページにページネーションと製品を表示するかどうかを決定するため、GetSize()が正しいカウントを持っていることを望んでいます。私は内側の結合、左結合、そしてより具体的にするためにコレクションの条件のみを使用しています。
この奇妙な問題を抱えている理由はありますか?
ありがとう
アップデート:
私の前の質問、 Magentoでコレクションをクローンする方法は? 1つのコレクションで2つの異なる操作を実行したかったのです。最初のコレクションには正しいgetSize()が表示されますが、GetSize()がゼロの場合、Where句を削除して、WHERE条件を新しいものにしました。この後、私は私が期待したことを正しいRAW SQLを取得し、MySQLでそれを実行することも正しいレコードセットを提供しますが、コレクションでのみGetSize()のみがゼロカウントを与えています。
したがって、基本的には、GetSize()が古いカウントを取っているので、コレクションをリロードする必要があるかもしれません。理にかなっていますか?
解決
コレクションのほとんど(すべてではないにしても)が拡張されます Varien_Data_Collection_Db
. 。このクラスの2つの方法は次のとおりです
public function getSize()
{
if (is_null($this->_totalRecords)) {
$sql = $this->getSelectCountSql();
$this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
}
return intval($this->_totalRecords);
}
public function count() //inherited from Varien_Data_Collection
{
$this->load();
return count($this->_items);
}
違いがあります。にとって getSize()
コレクションはロードされていません。にとって count()
そうです。通常、コレクションモデルは同じものを使用します getSize()
上記の方法とオーバーライドのみ getSelectCountSql()
.
の getSelectCountSql()
セットフィルターで利用可能なレコードの総数を取得するために、制限がリセットされます(where
声明)。方法をご覧ください getSelectCountSql()
作品
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
$countSelect->columns('COUNT(*)');
return $countSelect;
}
他のヒント
気をつけて。これは正しいですが、方法は上書きされます Varien_Data_Collection_Db
マリウスによって説明されているように
調べてみてください
// \Varien_Data_Collection::getSize
public function getSize()
{
$this->load();
if (is_null($this->_totalRecords)) {
$this->_totalRecords = count($this->getItems());
}
return intval($this->_totalRecords);
}
// \Varien_Data_Collection::count
public function count()
{
$this->load();
return count($this->_items);
}
したがって、この低レベルでは同じである必要があります。どちらの方法でもコレクションをロードし、アイテムをカウントします。
アップデート
ああ、私は問題を見ます:getsize()は_totalRecordsをキャッシュします、これはそれが再計算されないことを意味します。どこを確認してください _totalRecords
セットですか?
この答えは、Googleに「Magento Getsize誤解」と同様の検索のために表示されるので、誰かに役立つ可能性のあるシナリオを追加したいと思います
クエリにグループステートメントがあり、
SELECT COUNT(DISTINCT e.entity_id) ... GROUP BY ( at_id_art.value )
MySQLは各グループのカウントを返しますので、varien_data_collection_db :: getsize()は間違った答えを返します。これは、この関数が最初の行を取得するためです。
public function getSize()
{
if (is_null($this->_totalRecords)) {
$sql = $this->getSelectCountSql();
$this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
}
return intval($this->_totalRecords);
}
それが入力するとき
$this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
最初の行を選択するため、最初のグループの合計を合計サイズとして返します。
クエリの属性の一意の値に基づいて、このコードをカウントするためにカウントすることになりました。
$select = clone $collection->getSelect();
$group = $select->getPart(Zend_Db_Select::GROUP);
$select->reset(Zend_Db_Select::GROUP)->reset(Zend_Db_Select::COLUMNS)->columns("COUNT(DISTINCT {$group[0]})");
$totalCount = $collection->getConnection()->fetchOne($select);
ここに終わる場合に備えて、試してみる別の簡単な修正があります。
System -> Index Management
すべてを選択します(「グリーン、再インデックスは不要」を示していても、強制的に再インデックスになります。
これは私の空に解決しました getSize()
問題は、製品を見つけるための特別なデータベース要求を許可し、「IF」条件を満たし、適切にレンダリングします。
いつ count($collection)
とは違っていました $collection->getSize()
そうしなければならなかった reindex
製品、その後、すべてが正常に機能しました。
GetSize()には主な違いがあります()製品コレクションはロードされていません。 count()の場合、製品全体のコレクションをロードします。したがって、大きなカタログの場合、コレクションでカウント機能を使用することはお勧めできません。