[appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-28 Thread l.denardo
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  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.. > ancestor="false" source="manual">
> >          
> >          
> >          
> >      
>
> > 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 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 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  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  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:
>    source="manual">
>  
>  
>  
>  Here are my model definitions:
>  @PersistenceCapable(identityType = IdentityType.APPLICATION)
>  public class DeviceAddressEntity {
>      @PrimaryKey
>      @Persistent(valueStrategy = IdGeneratorStrategy.

Re: [appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-28 Thread Miroslav Genov
 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/source/browse/trunk/guestbook/src/guestbook/SearchJanitor.java 
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..
 
 
 
 


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 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 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-searchable-using-self.html

Regards
Lorenzo

On Jul 28, 1:33 am, Stephen Johnson  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  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:




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  searchTerms;
@Persistent(mappedBy = "searchIndex")
private DeviceAddressEntity address;
Here is body of my method that is executing the searching query:
   public List  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范impleName());
  for (String term : terms) {
query.addFilter("searchTerms",
com.google.appengine.api.datastore.Query.FilterOperator

Re: [appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-28 Thread Miroslav Genov

 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/source/browse/trunk/guestbook/src/guestbook/SearchJanitor.java 
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..







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 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 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-searchable-using-self.html

Regards
Lorenzo

On Jul 28, 1:33 am, Stephen Johnson  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  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:




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  searchTerms;
@Persistent(mappedBy = "searchIndex")
private DeviceAddressEntity address;
Here is body of my method that is executing the searching query:
   public List  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范impleName());
  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  add

[appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-28 Thread l.denardo
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  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  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:
> >  > source="manual">
> > 
> > 
> > 
>
> > 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 searchTerms;
>
> >   �...@persistent(mappedBy = "searchIndex")
> >    private DeviceAddressEntity address;
>
> > Here is body of my method that is executing the searching query:
> >   public List 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 addressKeys = Sets.newHashSet();
> >      PreparedQuery preparedQuery = datastoreService.prepare(query);
> >      Iterable 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 addresses = new
> > ArrayList(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 addresses = service.findAllAddresses(0,
> > 5, "my word");
>
> >      assertEquals("text search is not working
> > cor

[appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-28 Thread l.denardo

> 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

I can tell for sure, using Java, that there's a different behavior for
composite queries in the DevServer.
DevServer simply works without any index at all, returning correct
result sets also without the index.

Indexes for composite queries are not automatically generated, but
results are correct in the dev server. Then queries will return empty
sets in production because of the lack of index.
I think it's also stated somewhere (well hidden) in the documentation.

You have to manually configure the index and upload it to production
to get it working.

This is a confusing behavior, and maybe it's worth filing an issue
(requesting that the devserver fails like in production, maybe).

Regards
Lorenzo


On Jul 28, 1:33 am, Stephen Johnson  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  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:
> >  > source="manual">
> > 
> > 
> > 
>
> > 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 searchTerms;
>
> >   �...@persistent(mappedBy = "searchIndex")
> >    private DeviceAddressEntity address;
>
> > Here is body of my method that is executing the searching query:
> >   public List 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 addressKeys = Sets.newHashSet();
> >      PreparedQuery preparedQuery = datastoreService.prepare(query);
> >      Iterable 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 addresses = new
> > ArrayList(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.wit

[appengine-java] Re: Index over a list property on GAE not working as expected

2010-07-27 Thread Stephen Johnson
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  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:
>  source="manual">
> 
> 
> 
>
> 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 searchTerms;
>
>   �...@persistent(mappedBy = "searchIndex")
>    private DeviceAddressEntity address;
>
> Here is body of my method that is executing the searching query:
>   public List 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 addressKeys = Sets.newHashSet();
>      PreparedQuery preparedQuery = datastoreService.prepare(query);
>      Iterable 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 addresses = new
> ArrayList(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 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..  ancestor="false" source="manual">
>
>          
>          
>          
>      
>
> 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