package org.infinispan.all.embeddedquery;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.QueryBuilder;
import org.hibernate.search.exception.SearchException;
import org.infinispan.all.embeddedquery.testdomain.NumericType;
import org.infinispan.all.embeddedquery.testdomain.Person;
import org.infinispan.query.CacheQuery;
import org.infinispan.query.Search;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Clone of QueryPhrasesTest for uber jars.
*
* @author Jiri Holusa (jholusa@redhat.com)
* @author Anna Manukyan
*/
public class QueryPhrasesTest extends AbstractQueryTest {
private Person person1;
private Person person2;
private Person person3;
private Person person4;
protected String key1 = "test1";
protected String key2 = "test2";
protected String key3 = "test3";
private NumericType type1;
private NumericType type2;
private NumericType type3;
@Before
public void init() throws Exception{
cache = createCacheManager().getCache();
}
@After
public void after() {
cache.clear();
}
@Test
public void testBooleanQueriesMustNot() {
loadTestingData();
QueryBuilder queryBuilder = new QueryBuilder(STANDARD_ANALYZER);
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.must(queryBuilder.createBooleanQuery("name", "Goat")).not().createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(person1);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.must(queryBuilder.createBooleanQuery("name", "Goat")).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person3);
}
@Test
public void testBooleanQueriesShould() {
loadTestingData();
QueryBuilder queryBuilder = new QueryBuilder(STANDARD_ANALYZER);
Query subQuery = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().range()
.onField("age").below(20).createQuery();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.should(queryBuilder.createBooleanQuery("name", "Goat")).should(subQuery).createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(person1);
assert found.contains(person2);
assert found.contains(person3);
subQuery = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().range()
.onField("age").below(20).excludeLimit().createQuery();
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.should(queryBuilder.createBooleanQuery("name", "Goat")).should(subQuery).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person3);
}
@Test
public void testBooleanQueriesShouldNot() {
loadTestingData();
Query subQuery1 = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get()
.keyword().onField("name").boostedTo(0.5f)
.matching("Goat").createQuery();
Query subQuery2 = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get()
.range().onField("age").boostedTo(2f).below(20).createQuery();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.should(subQuery1).should(subQuery2).createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size());
assert found.get(0).equals(person1);
assert found.get(1).equals(person2);
assert found.get(2).equals(person3);
subQuery1 = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get()
.keyword().onField("name").boostedTo(3.5f)
.matching("Goat").createQuery();
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().bool()
.should(subQuery1).should(subQuery2).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(3, found.size());
assert found.get(0).equals(person2);
assert found.get(1).equals(person3);
assert found.get(2).equals(person1);
}
@Test
public void testFuzzyOnFieldsAndField() {
loadTestingData();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword().fuzzy().
onField("name").matching("Goat").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person3);
person4 = new Person();
person4.setName("Test");
person4.setBlurb("Test goat");
cache.put("testKey", person4);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword().fuzzy().
onField("name").andField("blurb").matching("goat").createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(person2);
assert found.contains(person3);
assert found.contains(person4);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword().fuzzy().
onFields("name", "blurb").matching("goat").createQuery();
List<Object> foundOnFields = Search.getSearchManager(cache).getQuery(query).list();
assertEquals(3, found.size());
assert found.contains(person2);
assert found.contains(person3);
assert found.contains(person4);
}
@Test
public void testFuzzyWithThresholdWithPrefixLength() {
person1 = new Person("yyJohn", "Eat anything", 10);
person2 = new Person("yyJonn", "Eat anything", 10);
cache.put(key1, person1);
cache.put(key2, person2);
//Ignore "yy" at the beginning (prefix==2), the difference between the remaining parts of two terms
//must be no more than edit distance -> return only 1 person
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword()
.fuzzy().withEditDistanceUpTo(1).withPrefixLength(2).onField("name").matching("yyJohny").createQuery();
List<Object> found = Search.getSearchManager(cache).getQuery(query).list();
assertEquals(1, found.size());
assertTrue(found.contains(person1));
//return all as edit distance excluding the prefix fit all documents
Query queryReturnAll = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword()
.fuzzy().withEditDistanceUpTo(2).withPrefixLength(2).onField("name").matching("yyJohn").createQuery();
List<Object> foundWithLowerThreshold = Search.getSearchManager(cache).getQuery(queryReturnAll).list();
assertEquals(2, foundWithLowerThreshold.size());
assertTrue(foundWithLowerThreshold.contains(person1));
assertTrue(foundWithLowerThreshold.contains(person2));
}
@Test
public void testQueryingRangeWithAnd() {
NumericType type1 = new NumericType(10, 20);
NumericType type2 = new NumericType(20, 10);
NumericType type3 = new NumericType(10, 10);
cache.put(key1, type1);
cache.put(key2, type2);
cache.put(key3, type3);
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class)
.get().range().onField("num1").andField("num2").below(20).excludeLimit().createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size()); //<------ All entries should be here, because andField is executed as SHOULD;
assert found.contains(type1);
assert found.contains(type2);
assert found.contains(type3);
NumericType type4 = new NumericType(11, 10);
cache.put("newKey", type4);
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(4, found.size());
assert found.contains(type3);
assert found.contains(type2);
assert found.contains(type1);
assert found.contains(type4);
//@TODO write here another case with not-matching entries
}
@Test(expected = SearchException.class)
public void testWildcardWithWrongName() {
loadTestingData();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword().wildcard()
.onField("wrongname").matching("Goat").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(2, found.size());
}
@Test
public void testWildcard() {
loadNumericTypes();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().keyword().wildcard()
.onField("name").matching("*wildcard*").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(type1);
assert found.contains(type2);
assert found.contains(type3);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().keyword().wildcard()
.onField("name").matching("nothing*").createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(0, found.size());
NumericType type4 = new NumericType(35, 40);
type4.setName("nothing special.");
cache.put("otherKey", type4);
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(type4);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().keyword().wildcard()
.onField("name").matching("*nothing*").createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(type2);
assert found.contains(type4);
}
@Test
public void testKeyword() {
loadTestingData();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword().onField("name")
.andField("blurb").matching("Eats").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(2, found.size());
person4 = new Person();
person4.setName("Some name with Eats");
person4.setBlurb("Description without keyword.");
cache.put("someKey", person4);
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(person2);
assert found.contains(person3);
assert found.contains(person4);
}
@Test
public void testPhraseSentence() {
loadTestingData();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().phrase()
.onField("blurb").sentence("Eats grass").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(person2);
person4 = new Person();
person4.setName("Another goat");
person4.setBlurb("Eats grass and drinks water.");
cache.put("anotherKey", person4);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person4);
}
@Test
public void testPhraseSentenceForNonAnalyzedEntries() {
loadNumericTypes();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().phrase()
.onField("name").sentence("Some string").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(0, found.size());
NumericType type4 = new NumericType(45,50);
type4.setName("Some string");
cache.put("otherKey", type4);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(type4);
}
@Test
public void testPhraseWithSlop() {
loadTestingData();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().phrase().withSlop(3)
.onField("blurb").sentence("Eats grass").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(person2);
person4 = new Person();
person4.setName("other goat");
person4.setBlurb("Eats green grass.");
cache.put("otherKey", person4);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person4);
person4.setBlurb("Eats green tasty grass.");
cache.put("otherKey", person4);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person4);
person4.setBlurb("Eats green, tasty, juicy grass.");
cache.put("otherKey", person4);
found = cacheQuery.list();
assertEquals(2, found.size());
assert found.contains(person2);
assert found.contains(person4);
person4.setBlurb("Eats green, tasty, juicy, fresh grass.");
cache.put("otherKey", person4);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(person2);
}
@Test
public void testPhraseWithSlopWithoutAnalyzer() {
loadNumericTypes();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().phrase().withSlop(1)
.onField("name").sentence("Some string").createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(0, found.size());
NumericType type = new NumericType(10, 60);
type.setName("Some string");
cache.put("otherKey", type);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(type);
NumericType type1 = new NumericType(20, 60);
type1.setName("Some other string");
cache.put("otherKey1", type1);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(type);
}
@Test
public void testAllExcept() {
loadTestingData();
Query subQuery = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().keyword()
.onField("name").matching("Goat").createQuery();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().all().except().createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(person2);
assert found.contains(person1);
assert found.contains(person3);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().all().except(query).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(0, found.size());
query = Search.getSearchManager(cache).buildQueryBuilderForClass(Person.class).get().all().except(subQuery).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(1, found.size());
assert found.contains(person1);
}
@Test
public void testAllExceptWithoutAnalyzer() {
loadNumericTypes();
Query subQuery = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().keyword()
.wildcard().onField("name").matching("*string*").createQuery();
Query query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().all().except().createQuery();
CacheQuery<Person> cacheQuery = Search.getSearchManager(cache).getQuery(query);
List<Person> found = cacheQuery.list();
assertEquals(3, found.size());
assert found.contains(type1);
assert found.contains(type2);
assert found.contains(type3);
query = Search.getSearchManager(cache).buildQueryBuilderForClass(NumericType.class).get().all().except(subQuery).createQuery();
cacheQuery = Search.getSearchManager(cache).getQuery(query);
found = cacheQuery.list();
assertEquals(0, found.size());
}
private void loadTestingData() {
person1 = new Person();
person1.setName("Navin Surtani");
person1.setBlurb("Likes playing WoW");
person1.setAge(20);
person2 = new Person();
person2.setName("Big Goat");
person2.setBlurb("Eats grass");
person2.setAge(30);
person3 = new Person();
person3.setName("Mini Goat");
person3.setBlurb("Eats cheese");
person3.setAge(25);
cache.put(key1, person1);
cache.put(key2, person2);
cache.put(key3, person3);
}
private void loadNumericTypes() {
type1 = new NumericType(10, 20);
type1.setName("Some string for testing wildcards.");
type2 = new NumericType(15, 25);
type2.setName("This string has nothing to do with wildcards.");
type3 = new NumericType(20, 30);
type3.setName("Some other string for testing wildcards.");
cache.put(key1, type1);
cache.put(key2, type2);
cache.put(key3, type3);
}
}