Glad to hear it! Anyway more information about automatic generation is available here
http://code.google.com/appengine/docs/java/datastore/queriesandindexes.html#Defining_Indexes_With_Configuration BTW there's the answer to everything in that: "Other forms of queries require their indexes to be specified in datastore-indexes.xml, including: * queries with multiple sort orders * queries with a sort order on keys in descending order [.....]" Your query seems to fall into the second case. I think that in case of errors like the one you found you can simply add the piece of XML to your datastore-indexes.xml. Many times you're not so lucky to get the missing index statement, and your queries simply return empty sets. Regards Lorenzo On Jul 28, 12:37 pm, Miroslav Genov <mgenov.j...@gmail.com> wrote: > It seems that the issue is with the sorting order. Now sorting order > has been removed and works like a charm. > > On 28.7.2010 ?. 13:22 ?., Miroslav Genov wrote: > > > First I wanna thank you all for the feedback. > > > Now I had looked into guestbook example at > >http://code.google.com/p/guestbook-example-appengine-full-text-search... > > and > > I had modified my code to use the same query generation. > > > Here is a snippet of my method that is doing searching job. > >http://pastebin.ca/1909986 > > > For my badness it seems that the result is same as in my last post. > > When I'm searching for a single word everything is working like a > > charm, but when I type "my word" 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 how can I enable the automatic indexing ? > > > In fact, in other part in our project is using same technique with the > > low level api and is working without any index definitions and etc. > > Here are some snippets how we are doing it: > > private List<Entity> getContractSearchIndexes(String query, String > > searchIndex, int offset, int pageSize) { > > timeLogger.start(); > > > String searchString = query.toLowerCase().trim(); > > log.info("Search for: " + searchString); > > > String[] terms = searchString.split("\\s"); > > > DatastoreService dataService = > > DatastoreServiceFactory.getDatastoreService(); > > Query searchQuery = new Query("ContractSearchIndex"); > > > for (String term : terms) { > > searchQuery.addFilter(searchIndex, Query.FilterOperator.EQUAL, > > term); > > } > > > List<Entity> indexes = > > dataService.prepare(searchQuery).asList(FetchOptions.Builder.withOffset(offset).limit(pageSize)); > > > timeLogger.resetAndLog("Search time"); > > > return indexes; > > } > > > The following code is working like a charm without any static index > > definitions and etc. The only difference between both indexes is the > > sorting order. In a few minutes I will try to remove it, so I can test > > what will happens without any ordering. > > > On 28.7.2010 ?. 12:06 ?., l.denardo wrote: > >> 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-searchabl... > > >> 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.get�SimpleName()); > >>>> 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(page�Size)); > >>>> 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.