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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.