MacFJA / php-redisearch

PHP Client for RediSearch
MIT License
67 stars 9 forks source link

Question: How to check if an index is already exisiting? #61

Open inpresif opened 1 year ago

inpresif commented 1 year ago

Right now, if you click refresh page you will get an error the index exists:

Fatal error: Uncaught Predis\Response\ServerException: Index already exists in /var/www/html/vendor/predis/predis/src/Client.php

Any way to verify if it already exists and if so, move on to setting the index without creating it First? Try/Catch didn't work.

EDIT:

Adding a question since it's not documented :-). It this the correct way to add arguments?

$builder->setIndex($index_name)
  ->addTextField('uuid')
  ->addTextField('title')
  ->addTextField('content')
  ->addVectorField('title_vector', 'FLAT', 'float', $title_vector_dim, $distance_metric)
  ->addVectorField('content_vector', 'FLAT', 'float', $content_vector_dim, $distance_metric)
  ->addNumericField('tokens')
  ->setTemporary(3600)   <------ ADDING ARGS LIKE THIS
  ->create($client);
MacFJA commented 1 year ago

Any way to verify if it already exists and if so, move on to setting the index without creating it First?

You can use the FT._LIST command to get this information:

use  MacFJA\RediSearch\Redis\Command\IndexList;
$list = $client->execute(new IndexList());
if (!in_array($index_name, $list, true)) {
  // Create index
}

It's what I have done in the side library: https://github.com/MacFJA/php-redisearch-integration/blob/main/src/ObjectWorker.php#L227 (But it also checks if the index definition is in sync with Redis)


Adding a question since it's not documented :-). It this the correct way to add arguments?

Yes, it's how is should be done. If your IDE/Text Editor support it, the autocompletion should display the list of method available an the type of its arguments (The list is here: https://github.com/MacFJA/php-redisearch/blob/main/src/IndexBuilder.php#L43-L92)

MacFJA commented 1 year ago

Adding a question since it's not documented :-). It this the correct way to add arguments?

You can also look at the Unit Tests:

As the code coverage is high (97% of lines), in most case, there is, at least, one test that cover a functionality

inpresif commented 1 year ago

You rock! Thanks.

If your IDE/Text Editor support it,

Strangely enough my VSC didn't pick up on these but I saw them in the IndexBuilder :) Next stop: getting it all into Slim4.

About the setTemporary() agument, one of the other repos' stated it would be/could be reset on each visit, so as long at it is used it will reset to n-time / restart instead of expiring. Is that the case here as well? If not we'll make it last longer.

inpresif commented 1 year ago

image

Not sure if the time-out works though, see image.

Here's one added the normal way, which does work:

image

EDIT (again, sorry): it's a few hours later and those keys seem to be gone after all. Must be some misrepresentation in Redis stack browser. The keys have no expiration, but the entire index of course has. Maybe it helps future confused folks like myself :)

inpresif commented 1 year ago

Yes, it's how is should be done. If your IDE/Text Editor support it, the autocompletion should display the list of method available an the type of its arguments (The list is here: https://github.com/MacFJA/php-redisearch/blob/main/src/IndexBuilder.php#L43-L92)

Any chance there's a list of what results we can esasily retrieve from the $results = $client->execute($search); instance?

MacFJA commented 1 year ago

EDIT (again, sorry): it's a few hours later and those keys seem to be gone after all. Must be some misrepresentation in Redis stack browser. The keys have no expiration, but the entire index of course has. Maybe it helps future confused folks like myself :)

Yes, it's not the document that have expiration, but the index itself As the documentation say:

temporary index that expires after a specified period of inactivity, [...} When temporary indexes expire, they drop all the records associated with them.


Any chance there's a list of what results we can esasily retrieve from the $results = $client->execute($search); instance?

It's impossible to have the typing as the execute method only know that the input parameter is a Command. But some command have a dedicated result class like:

For those cases, you can use $result instanceof InfoResponse to known how to handle the result.

The response of the rest of command are generally just "OK", a number, a string, a list of string ; which are not worth the need of a dedicated class.

Except for commands where results are a bit complex, the library is just a fine wrapper around the raw Redis command

inpresif commented 1 year ago

Thanks. I'm working my way to better understanding this Redisearch engine small steps at a time before I'm rolling this out to our project.

I'm just trying to get the returned result into an array of keys/values. I can print_r the results fine, but I'm not too experienced in Instances and how they operate (I'm from PHP3+ so I'm stuck to old non OOP mindsets, trying to better myself ;-)).

$search = new \MacFJA\RediSearch\Redis\Command\Search();
$search->setIndex($index_name)->setQuery('dickens');
$results =  $client->execute($search);
echo '<br><pre>';
print_r($results);
echo '</pre><br>';

Thanks again, I'll try some of the things mentioned.

MacFJA commented 1 year ago

The result of a Search command is encapsulated into a PaginatedResponse object which hold the first page of documents (10 by default in RediSearch) and you can get documents and request the next page.

In the sister library I create an iterator to help to retrieve all the result: https://github.com/MacFJA/php-redisearch-integration/blob/main/src/Iterator/ResponseItemIterator.php: you put the command result into the ResponseItemIterator and you can to a simple foreach to read all the document one after the other

inpresif commented 1 year ago

If you mean something like this, then that does not work (Fatal error: Uncaught Error: Class "ResponseItemIterator" not found).

$iterator = new \MacFJA\RediSearch\Integration\Iterator\ResponseItemIterator($result);

foreach ($iterator as $document) {
  echo json_encode($document) . "\n";
}

I feel like an idiot about now, so I'm moving on to storing data in our MySQL DB, that'll take me 5 minutes to do instead of days :).

Earlier, I also got errors on trying a search like this: $result = $client->ftsearch($index_name, $query); It is time to move on and get back to this later. For now it is stalling our main delivery progress.

Thanks again for your time, effort and help.

MacFJA commented 1 year ago

If you mean something like this, then that does not work (Fatal error: Uncaught Error: Class "ResponseItemIterator" not found).

You need to install an extra package: https://packagist.org/packages/macfja/redisearch-integration to be able to use the ResponseItemIterator


Earlier, I also got errors on trying a search like this: $result = $client->ftsearch($index_name, $query);

To enable command aliases, you need to register them as describe here: https://github.com/MacFJA/php-redisearch#use-predis-v1x-shorthand-syntax But be careful, it's only available for Predis 1 (version 1 haven't been update for a year, and as the version 2 is now out, I don't expect it to be updated anymore)