WIP / DEBUG

- add stopwatches to find slow parts.
- to test : add api-v3/searchraw ; same as "search", but returns raw es docs (shortest way). No objects, no fractal.
This commit is contained in:
jygaulier
2020-10-21 13:55:08 +02:00
parent d0bec62dc0
commit d0283913de
4 changed files with 132 additions and 2 deletions

View File

@@ -13,6 +13,7 @@ use Alchemy\Phrasea\Fractal\CallbackTransformer;
use Alchemy\Phrasea\Fractal\IncludeResolver;
use Alchemy\Phrasea\Fractal\SearchResultTransformerResolver;
use Alchemy\Phrasea\Fractal\TraceableArraySerializer;
use Alchemy\Phrasea\Media\MediaSubDefinitionUrlGenerator;
use Alchemy\Phrasea\Model\Manipulator\UserManipulator;
use Alchemy\Phrasea\Model\RecordReferenceInterface;
use Alchemy\Phrasea\Record\RecordCollection;
@@ -44,12 +45,20 @@ use media_subdef;
use record_adapter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Alchemy\Phrasea\Utilities\Stopwatch;
class V3SearchController extends Controller
{
use JsonBodyAware;
use DispatcherAware;
public function searchRawAction(Request $request)
{
$result = $this->doSearchRaw($request);
return Result::create($request, $result)->createResponse();
}
/**
* Search for results
*
@@ -59,6 +68,8 @@ class V3SearchController extends Controller
*/
public function searchAction(Request $request)
{
$stopwatch = new Stopwatch();
$subdefTransformer = new SubdefTransformer($this->app['acl'], $this->getAuthenticatedUser(), new PermalinkTransformer());
$technicalDataTransformer = new TechnicalDataTransformer();
$recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer);
@@ -99,8 +110,12 @@ class V3SearchController extends Controller
// and push everything back to fractal
$fractal->parseIncludes($this->getIncludes($request));
$tim0 = $stopwatch->getElapsedMilliseconds();
$result = $this->doSearch($request);
$tim1 = $stopwatch->getElapsedMilliseconds();
$story_children_limit = null;
// if searching stories
if ($request->get('search_type') == 1) {
@@ -114,8 +129,20 @@ class V3SearchController extends Controller
$story_children_limit
);
$tim2 = $stopwatch->getElapsedMilliseconds();
$ret = $fractal->createData(new Item($searchView, $searchTransformer))->toArray();
$tim3 = $stopwatch->getElapsedMilliseconds();
$ret['__timers__'] = [
'_where_' => sprintf("%s::%s", __FILE__, __METHOD__),
'boot' => $tim0,
'doSearch' => $tim1,
'buildSearchView' => $tim2,
'fractal' => $tim3,
];
return Result::create($request, $ret)->createResponse();
}
@@ -313,6 +340,23 @@ class V3SearchController extends Controller
return $resultView;
}
private function doSearchRaw(Request $request)
{
list($offset, $limit) = V3ResultHelpers::paginationFromRequest($request);
$options = SearchEngineOptions::fromRequest($this->app, $request);
$options->setFirstResult($offset);
$options->setMaxResults($limit);
$this->getSearchEngine()->resetCache();
$search_result = $this->getSearchEngine()->queryraw((string)$request->get('query'), $options);
$this->getSearchEngine()->clearCache();
return $search_result;
}
/**
* @param Request $request
* @return SearchEngineResult
@@ -432,8 +476,10 @@ class V3SearchController extends Controller
return !isset($fakeSubdefs[spl_object_hash($subdef)]);
})
);
$urls = $this->app['media_accessor.subdef_url_generator']
->generateMany($this->getAuthenticatedUser(), $allSubdefs, $urlTTL);
/** @var MediaSubDefinitionUrlGenerator $urlGenerator */
$urlGenerator = $this->app['media_accessor.subdef_url_generator'];
$urls = $urlGenerator->generateMany($this->getAuthenticatedUser(), $allSubdefs, $urlTTL);
$subdefViews = [];

View File

@@ -83,6 +83,11 @@ class V3 extends Api implements ControllerProviderInterface, ServiceProviderInte
*/
$controllers->match('/search/', 'controller.api.v3.search:searchAction');
/**
* @uses V3SearchController::searchRawAction()
*/
$controllers->match('/searchraw/', 'controller.api.v3.search:searchRawAction');
/**
* @uses V3RecordController::indexAction_GET()
*/

View File

@@ -331,6 +331,53 @@ class ElasticSearchEngine implements SearchEngineInterface
);
}
public function queryraw($queryText, SearchEngineOptions $options = null)
{
$options = $options ?: new SearchEngineOptions();
$context = $this->context_factory->createContext($options);
/** @var QueryCompiler $query_compiler */
$query_compiler = $this->app['query_compiler'];
$queryAST = $query_compiler->parse($queryText)->dump();
$queryCompiled = $query_compiler->compile($queryText, $context);
$queryESLib = $this->createRecordQueryParams($queryCompiled, $options, null);
// ask ES to return field _version (incremental version number of document)
$queryESLib['body']['version'] = true;
$queryESLib['body']['from'] = $options->getFirstResult();
$queryESLib['body']['size'] = $options->getMaxResults();
if($this->options->getHighlight()) {
$queryESLib['body']['highlight'] = $this->buildHighlightRules($context);
}
$aggs = $this->getAggregationQueryParams($options);
if ($aggs) {
$queryESLib['body']['aggs'] = $aggs;
}
$res = $this->client->search($queryESLib);
// return $res;
$results = [];
foreach ($res['hits']['hits'] as $hit) {
$results[] = $hit;
}
/** @var FacetsResponse $facets */
$facets = $this->facetsResponseFactory->__invoke($res);
return [
'results' => $results,
'took' => $res['took'], // duration
'count' => count($res['hits']['hits']), // available
'total' => $res['hits']['total'], // total
'facets' => $facets->toArray()
];
}
private function createRecordQueryParams($ESQuery, SearchEngineOptions $options, \record_adapter $record = null)
{
$params = [

View File

@@ -0,0 +1,32 @@
<?php
namespace Alchemy\Phrasea\Utilities;
class Stopwatch
{
private $_start;
public function __construct()
{
$this->reset();
}
private function reset()
{
$this->_start = microtime(true);
}
/**
* returns the elapsed time in msec and reset
*
* @return float
*/
public function getElapsedMilliseconds()
{
$e = (microtime(true) - $this->_start) * 1000.0 ; // micro to milli
$this->reset();
return $e;
}
}