tomwalder / php-appengine-search

Native Full Text Search for PHP on Google App Engine
Apache License 2.0
24 stars 4 forks source link

Get document ID of the newly inserted document #14

Closed emilorol closed 6 years ago

emilorol commented 8 years ago

Hi Tom,

Using a similar structure or logic as the links I added in #13 now when I create an entity on the datastore I also created it on the document for the search. It is all working and it was simpler than I could have imagined. The only caveat is to match schema at the field name for both the search and the data store.

      // Save post
      $this->post->writeData($data);

      // Save tag name instead of tag ID on the search document
      $tag = $this->tag->getEntityByID($data['tag']);
      $data['tag'] = $tag['name'];

      $doc = $this->search->createDocument($data);

The problem now is that if I change or edit my entity and save it, a new document will be created. It will make more sense to update the existing document or to at least delete it and create a new one.

kaizendeveloper commented 7 years ago

I had the same problem as you, I mean, that after inserting | updating an entity, it's key dissapeared, I've discovered by accident that you actually need to allocated the ID through allocateId method of the DatastoreClient class. From this point on, the fresh entity PHP object will allow you to do further updates at will, and the id doesn't vanish anymore. I hope this helps.

emilorol commented 7 years ago

Thank you for posting an answer. Can you share some code?

kaizendeveloper commented 7 years ago

For sure. For example, I expected that the $newUser object (which is an entity) after upserting it would maintain or at least retrieve the alphanumerical automatic key name, but after that update I could not work directly on that entity for further property modifying.

This code won't work as I expected ($this->ds_client contains the DatastoreClient instance): (Method createNewEntityButDontSave will create an entity with auto id by just defining a kind)

$newUser = $this->createNewEntityButDontSave();
$newUser->name = 'Bob';
$this->ds_client->upsert($newUser); //Here it saves the entity, no problem here
//I wanted to add other properties after saving
$newUser->money_spent = 10;
$this->ds_client->upsert($newUser); //This will throw an exception because the key doesn't exist inside the object

But if I do this (before the first upsert)

if(!is_null($newUser->key()->pathEndIdentifier())){
    $this->ds_client->allocateId($newUser->key());
}

Now after the upsert the entity will be ready for reuse as many times you want, and if you want to know what was the id assigned you can get i through $newUser->key()->pathEndIdentifier()

Now the new simplified whole thing:

$newUser = $this->createNewEntityButDontSave();
$newUser->name = 'Bob';

if(!is_null($newUser->key()->pathEndIdentifier())){
    $this->ds_client->allocateId($newUser->key());
}
$this->ds_client->upsert($newUser); //Here it saves the entity, no problem here
//I can add or modify attributes
$newUser->money_spent = 10;
$this->ds_client->upsert($newUser); //This will work
emilorol commented 7 years ago

Thank you for sharing the code. If it is not to much trouble can you format it with the markup? That will make it easier to read.

Like:

print 'code here';

Thank you

kaizendeveloper commented 7 years ago

Of course, just didn't know how to use the embedded marking tool, I've updated the example.

emilorol commented 7 years ago

Thank you very much that helps a lot.