cakephp / elastic-search

Elastic search datasource for CakePHP
Other
88 stars 53 forks source link

Result from searching all indexes are not converted to documents #72

Closed burzum closed 4 years ago

burzum commented 8 years ago

As described here you can search through all types like this:

/_search

This can be done using the plugin by getting any type:

$type = TypeRegistry::get('Profiles');
$type->name('');
$results = $type->find()->all();
debug($resutls);

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.

lorenzo commented 8 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.

burzum commented 8 years ago

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.

lorenzo commented 8 years ago

You have two ways, but I think this way is the one that should be explored first:

If that works correctly for you, we can formalize this process into the plugin

burzum commented 8 years ago

OK, thanks.

burzum commented 8 years ago

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?

lorenzo commented 8 years ago

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

burzum commented 8 years ago

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.

github-actions[bot] commented 4 years ago

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