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.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.

Reply via email to