Getting back to the original question, since the error appears to be for the second query and it's only a get (no composite index), probably it's only a matter of automatic indexing being disabled.
Just as a pointer on text search, there's a post here: http://googleappengine.blogspot.com/2010/04/making-your-app-searchable-using-self.html Regards Lorenzo On Jul 28, 1:33 am, Stephen Johnson <onepagewo...@gmail.com> wrote: > Hi Miroslav, > Yes, I would say it is working on your local dev. because you have > automatic indexes enabled and so is automatically creating the > necessary index for you but then you are not deploying this > automatically generated index. It looks like your code splits search > phrases into individual words and applies an AND in you query filter > for each word, thus the search for "my word" becomes the filter: > > searchTerms == 'my' && searchTerms == 'word' > > Thus, this requires a composite index consisting of searchTerms twice. > If you want to search for "my word" don't split it apart, just have > the filter have > > searchTerms == 'my word' > > I believe this should do the trick. > Stephen > > On Jul 27, 3:06 am, Miroslav Genov <mgenov.j...@gmail.com> wrote: > > > Hello, > > I'm encountering a strange issue with datastore list property indexes > > when I'm trying to use them in a full-text search queries. > > > Here are my index definition, my model definitions, my sample code and > > my test code, and the error that I'm getting when my app is deployed on > > GAE. > > > Here is my searching index: > > <datastore-index kind="DeviceAddressSearchIndex" ancestor="false" > > source="manual"> > > <property name="searchTerms" direction="asc"/> > > <property name="identifier" direction="desc"/> > > </datastore-index> > > > Here are my model definitions: > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > public class DeviceAddressEntity { > > �...@primarykey > > �...@persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > private Key key; > > > �...@persistent > > private String identifier; > > .... > > .... > > �...@persistent > > private DeviceAddressSearchIndex searchIndex; > > > and my search index > > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > > public class DeviceAddressSearchIndex { > > > �...@primarykey > > �...@persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > private Key id; > > > �...@persistent > > private Integer identifier; > > > �...@persistent > > private Date date; > > > �...@persistent > > private Set<String> searchTerms; > > > �...@persistent(mappedBy = "searchIndex") > > private DeviceAddressEntity address; > > > Here is body of my method that is executing the searching query: > > public List<DeviceAddressEntity> findAllAddresses(Integer offset, > > Integer pageSize, String searchQuery) { > > > String[] terms = {}; > > if (!Strings.empty(searchQuery)) { > > String searchTerms = searchQuery.toLowerCase(); > > terms = searchTerms.split("\\s"); > > } > > com.google.appengine.api.datastore.Query query = new > > com.google.appengine.api.datastore.Query(DeviceAddressSearchIndex.class.getSimpleName()); > > for (String term : terms) { > > query.addFilter("searchTerms", > > com.google.appengine.api.datastore.Query.FilterOperator.EQUAL,term); > > } > > > query.setKeysOnly(); > > > query.addSort("identifier", > > com.google.appengine.api.datastore.Query.SortDirection.DESCENDING); > > > Set<Key> addressKeys = Sets.newHashSet(); > > PreparedQuery preparedQuery = datastoreService.prepare(query); > > Iterable<Entity> addressEntities = > > preparedQuery.asIterable(FetchOptions.Builder.withOffset(offset).limit(pageSize)); > > for (Entity entity : addressEntities) { > > addressKeys.add(entity.getParent()); > > } > > > if (addressKeys.size() == 0) { > > return Lists.newArrayList(); > > } > > /** we are not using batches, cause mostly this search is for 5-10 > > elements max. */ > > List<DeviceAddressEntity> addresses = new > > ArrayList<DeviceAddressEntity>(addressKeys.size()); > > for (Key key : addressKeys) { > > DeviceAddressEntity address = > > pm.get().getObjectById(DeviceAddressEntity.class,key); > > addresses.add(address); > > } > > } > > > Here is my test that is testing how full text search is working > > �...@test > > public void findAddressesUsingTextSearch() { > > final DeviceAddressEntity first = DeviceAddressEntity.with("56", > > NORMALIZED_MAC, "my first word", "33", "10", "11", "12", "13", "14"); > > final DeviceAddressEntity second = DeviceAddressEntity.with("57", > > NORMALIZED_MAC, "my second word", "9", "10", "11", "12", "13", "14"); > > final DeviceAddressEntity third = DeviceAddressEntity.with("58", > > NORMALIZED_MAC, "otherword", "9", "10", "11", "12", "13", "14"); > > > MonitoringService service = > > injector.getInstance(MonitoringService.class); > > service.saveDeviceAddress("56", first); > > service.saveDeviceAddress("57", second); > > > List<DeviceAddressEntity> addresses = service.findAllAddresses(0, > > 5, "my word"); > > > assertEquals("text search is not working > > correctly?",2,addresses.size()); > > } > > > and this test is passing > > > When app is deployed on GAE and when I type "my" in the search box, the > > method is returning correct results, but when I type "my word" the > > datastore is throwing the following exception: > > com.google.appengine.api.datastore.DatastoreNeedIndexException: no > > matching index found.. <datastore-index kind="DeviceAddressSearchIndex" > > ancestor="false" source="manual"> > > > <property name="searchTerms" direction="asc"/> > > <property name="searchTerms" direction="asc"/> > > <property name="identifier" direction="desc"/> > > </datastore-index> > > > Any idea what is causing this ? -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-j...@googlegroups.com. To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.