Incorrect Key in Datastore - google-app-engine

Write to datastore
Key dataKey = KeyFactory.createKey("Datastore", "123");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity data = new Entity("Datastore", dataKey);
data.setProperty("date", date);
try{
datastore.get(dataKey);
datastore.delete(dataKey);
}catch(EntityNotFoundException ex){
log.serve("Error : "+ ex.getMessage());
}
datastore.put(data);
Read from datastore
Key dataKey = KeyFactory.createKey("Datastore", "123");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity entity = datastore.get(dataKey);
I have 02 questions:
1. I use datastore.get(dataKey) to check whether the entity is existed or not, because I want to avoid duplicated entity with same key but I don't think the way i'm using is good. Is there any other way can do it better?
2. I can't get data back. It said that " No entity was found matching the key: Datastore("123")"
I read google datastore documentation again and again but I still can't find out what wrong with this :(.
Can somebody help me please ?
Thank you.

Replace:
Entity data = new Entity("Datastore", dataKey)
with:
Entity data = new Entity(dataKey)
Also you don't need to worry about duplicates, if you commit an existing entry (which its key is already in the datastore) it will be override. There can't be two same keys in the datastore.

Related

objectify cache not working

I am using GAE for my server where I have all my entities in Datastore. One of the entity has more than 2000 records, and it is taking almost 30 secs to read whole entity. So I wanted to use cache to improve performance.
I have tried Datastore objectify #cache annotation, but not finding
how to read from the stored cache. I have declared entity as below:
#Entity
#Cache
public class Devices{
}
Second thing I tried is memcache. I am storing whole List s
in key, but this is not storing, I couldn't see in console memcache,
but at the same time not showing any errors or exceptions while
storing objects.
putvalue("temp", List<Devices>)
public void putValue(String key, Object value) {
Cache cache = getCache();
logger.info(TAG + "getCache() :: storing memcache for key : " + key);
try {
if (cache != null) {
cache.put(key, value);
}
}catch (Exception e) {
logger.info(TAG + "getCache() :: exception : " + e);
}
}
When I tried to retrieve using getValue("temp"), it is returning
null or empty.
Object object = cache.get(key);
My main object is to limit the time to 5secs to get all the records of entity.
Can anyone suggest what I am doing wrong here? Or any better solution to retrieve the records fast from Datastore.
Datastore Objectify actually uses the App Engine Memcache service to cache your entity data globally when you use the #Cache annotation. However, as explained in the doc here, only get-by-key, save(), and delete() interact with the cache. Query operations are not cached.
Regarding the App Engine Memcache method, you may be hitting the limit for the maximum size of a cached data value which is 1 MiB, although I believe this raise an exception indeed.
Regarding the query itself, you may be better off using a keys_only query and then doing a key.get() on each returned key. That way, Memcache will be used for each record.

Delete ndb entity using the key.id()

I have the key id of the entity I want to delete, but when trying to delete using get_by_id, it is not deleting the entity (it's not doing anything).
The numerical id (I assume its a number, not a string) is stored in the 'key' get data:
d = car_database.Car()
ident = self.request.get('key')
d.get_by_id(ident).delete()
The id in this instance is: 5659313586569216
Thanks for the help
This is incorrect. Please look at the documentation on deleting entities - https://cloud.google.com/appengine/docs/python/ndb/entities#deleting_entities - it's pretty clear what you should be doing.
In your case you should be
ident = self.request.get('key')
d = car_database.Car.get_by_id(ident)
if d:
d.key.delete()
Note that get_by_id is in fact a classmethod so you don't need to instantiate in instance of Car to use it.
And delete is a method of the Key, not of Model.

Google App Engine - Recommended approach for querying by Ids

Anyone can recommend the better approach for querying entities by multiple ids from GAE HRD datastore ?
1.
mgr = getEntityManager();
Query dbQuery = mgr.createQuery("SELECT FROM CustomEntity as CustomEntity WHERE id IN (:ids)");
dbQuery.setParameter("ids", results.getIds());
return (List<CustomEntity>) dbQuery.getResultList();
2.
List<Key> customEntityKeys = new ArrayList<Key>();
for (String id : results.getIds()) {
customEntityKeys.add(KeyFactory.createKey("CustomEntity", id));
}
mgr = getEntityManager();
JPADatastoreBridge jpaBridge = new JPADatastoreBridge();
List<CustomEntity> customEntities = new ArrayList<CustomEntity>();
Map<Key,Entity> customEntityMap = datastore.get(customEntityKeys);
for (Entity customEntityEntity : customEntityMap.values()) {
customEntities.add((CustomEntity) jpaBridge.getJPAFromEntity(customEntityEntity, mgr, CustomEntity.class));
}
return customEntities;
In "better approach" i mean mainly performance wise. also, if there is another way I'll be happy to hear about it.
Thanks.
p.s.
Im using JPA as my persistance method. Not sure if this really matters.
I don't know about most of the code, but if you're asking whether you should use Query("SELECT.... WHERE ID IN....") or datastore.get(...), the second is much, much better. Gets are significantly more efficient than queries with the App Engine datastore - not to mention the fact that they are always strongly consistent, whereas non-ancestor queries are only eventually consistent.

How to search Entities effectively in google datastore

I am using Datastore low level APIs for an application (Internal job portal).
I have an entity called Candidate with following properties
Entity cadidate=new Entity("Candidate",getEmpNum());
candidate.setProperty("name","some name");
candidate.setProperty("skill","c++,Java,C#,GAE");
candiate.setProperty("empNum");
The property 'skill' takes the a comma seperated string. If an HR do a search for a candidate with a key
"GAE,Java" , how do I effectively search for entities?
will the following query works?
q.addFilter(searchBy, FilterOperator.GREATER_THAN_OR_EQUAL, searchFor);
q.addFilter(searchBy, Query.FilterOperator.LESS_THAN, searchFor+"Z");
If the above query works on say 1000 Entities ..does it work with same latency when there are 50,000 + entities in the datastore?
Please suggest me .. I am new to GAE and Datastore
-thanks
Ma
You should use list property.
List<String> skills = Arrays.asList("c++", "Java", "C#", "GAE");
candidate.setProperty("skill", skills);
then query with IN operator:
List<String> findSkills = Arrays.asList("Java","GAE");
q.addFilter("skill", FilterOperator.IN, findSkills);
This

How to convert com.google.appengine.api.datastore.Entity to my Entity Object?

Why I get an casting error when I try to get some database object using com.google.appengine.api.datastore.Query
For example:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("User");
PreparedQuery pq = datastore.prepare(q);
for (Entity entity : pq.asIterable()) {
User myUser = (User)entity;
}
You can not do that. Entities returned are of type Entity and in java you can not just cast one type to another.
If you want queries to return objects of custom type, you need some kind of mapping framework, for example objectify. It lets you directly use your classes in database operations.

Resources