Closed burzum closed 4 years ago
That's actually by design. But this design choice is does not prevent having a mapper function casting to the right Document type if needed. If you want to implement this mapper, please let me know so that I can guide you.
If you want to implement this mapper, please let me know so that I can guide you.
Please guide me. :) Are you talking about using map reduce for this? Just let me know what I need / should consider, I can read the book.
You have two ways, but I think this way is the one that should be explored first:
formatResults()
to your findermap()
each resulttype
of the documenttype_name => Type class
new $correctDocumentClass($oldDocument->_result)
; (You will need a getter for the _result property)If that works correctly for you, we can formalize this process into the plugin
OK, thanks.
That's a hell of a workaround:
$query->formatResults(function (\Cake\ElasticSearch\ResultSet $results) {
return $results->map(function ($row) {
if (method_exists($row, 'getResult')) {
$originalResult = $row->getResult();
$resultType = $originalResult->getType();
$resultType = Inflector::singularize($resultType);
$resultType = Inflector::classify($resultType);
$documentClass = \Cake\Core\App::className($resultType, 'Model/Document');
if (class_exists($documentClass)) {
$row = new $documentClass($originalResult->getData());
}
}
return $row;
});
});
That works for me but I think there should be a better, more convenient way of doing this? Also this will not work with plugins.
Maybe we can add a map of type -> document class to the connection config and instead of doing all the checks and instantiating a 2nd document get the right one directly?
As I said before, the main challenge of this feature is having a way to map types form elastic search to type classes in PHP. I firmly thing that there should not be a magic solution for this, instead, it should probably be provided as a configuration parameter or function parameter when doing the find
If you do it inside the find it will become repetitive again. There should be a single place to put the mapping into. Also doing
$type = TypeRegistry::get('Profiles');
$type->name('');
feels somehow strange. The API is not very intuitive. I don't have a good idea how to improve this right now. Maybe adding a method to the query that gets a generic instance and configures it to search all types?
$query->allTypes()->typeMap(['foo' => 'bar'])->where([/*...*/])->all();
If this is possible at all coming from there.
This issue is stale because it has been open for 120 days with no activity. Remove the stale
label or comment or this will be closed in 15 days
As described here you can search through all types like this:
/_search
This can be done using the plugin by getting any type:
The problem with that is now that all of the documents are of the type that belongs to the type class instance: Profiles.
But the elastic search result set contains the type information. I think the plugin should map the type based on that information to the correct document class.