/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.usergrid.persistence; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.usergrid.AbstractCoreIT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class GeoQueryBooleanTest extends AbstractCoreIT { private static final Logger logger = LoggerFactory.getLogger( GeoQueryBooleanTest.class ); public GeoQueryBooleanTest() { super(); } @Test public void testGeoQueryWithOr() throws Exception { logger.info( "GeoQueryBooleanTest.testGeoQueryWithOr" ); EntityManager em = app.getEntityManager(); assertNotNull( em ); // create two users at a location Map<String, Object> properties = new LinkedHashMap<String, Object>() {{ put( "username", "ed" ); put( "employer", "Apigee" ); put( "email", "ed@example.com" ); put( "location", new LinkedHashMap<String, Object>() {{ put("latitude", 37.776753 ); put("longitude", -122.407846 ); }} ); }}; Entity user1 = em.create( "user", properties ); assertNotNull( user1 ); properties = new LinkedHashMap<String, Object>() {{ put( "username", "fred" ); put( "employer", "Microsoft" ); put( "email", "fred@example.com" ); put( "location", new LinkedHashMap<String, Object>() {{ put("latitude", 37.776753 ); put("longitude", -122.407846 ); }} ); }}; Entity user2 = em.create( "user", properties ); assertNotNull( user2 ); app.waitForQueueDrainAndRefreshIndex(); // define center point about 300m from that location final double lat = 37.774277; final double lon = -122.404744 ; Query query = Query.fromQL( "select * where location within 400 of " + lat + "," + lon); Results listResults = em.searchCollection( em.getApplicationRef(), "users", query ); assertEquals( 2, listResults.size() ); query = Query.fromQL( "select * where employer='Apigee' or location within 100 of " + lat + "," + lon); listResults = em.searchCollection( em.getApplicationRef(), "users", query ); // no results because geo filter applied after query even in the case or 'or' assertEquals( 1, listResults.size() ); query = Query.fromQL( "select * where employer='Apigee' or location within 400 of " + lat + "," + lon); listResults = em.searchCollection( em.getApplicationRef(), "users", query ); // only one result because geo filter applied after query even in the case or 'or' assertEquals( 2, listResults.size() ); } @Test public void testGeoQueryWithNot() throws Exception { logger.info( "GeoQueryBooleanTest.testGeoQueryWithOr" ); EntityManager em = app.getEntityManager(); assertNotNull( em ); // define two users at a location Map<String, Object> properties = new LinkedHashMap<String, Object>() {{ put( "username", "bart" ); put( "email", "bart@example.com" ); put( "block", new ArrayList<Object>() {{ add( new LinkedHashMap<String, Object>() {{ put("name", "fred"); }}); add( new LinkedHashMap<String, Object>() {{ put("name", "gertrude"); }}); add( new LinkedHashMap<String, Object>() {{ put("name", "mina"); }}); }}); put( "blockedBy", new ArrayList<Object>() {{ add( new LinkedHashMap<String, Object>() {{ put("name", "gertrude"); }}); add( new LinkedHashMap<String, Object>() {{ put("name", "isabell"); }}); }}); put( "location", new LinkedHashMap<String, Object>() {{ put("latitude", 37.776753 ); put("longitude", -122.407846 ); }}); }}; Entity userBart = em.create( "user", properties ); assertNotNull( userBart ); properties = new LinkedHashMap<String, Object>() {{ put( "username", "fred" ); put( "email", "fred@example.com" ); put( "block", new ArrayList<Object>() {{ add( new LinkedHashMap<String, Object>() {{ put("name", "steve"); }}); add( new LinkedHashMap<String, Object>() {{ put("name", "mina"); }}); }}); put( "blockedBy", new ArrayList<Object>() {{ add( new LinkedHashMap<String, Object>() {{ put("name", "bart"); }}); add( new LinkedHashMap<String, Object>() {{ put("name", "beth"); }}); }}); put( "location", new LinkedHashMap<String, Object>() {{ put("latitude", 37.776753 ); put("longitude", -122.407846 ); }} ); }}; Entity userFred = em.create( "user", properties ); assertNotNull( userFred ); app.waitForQueueDrainAndRefreshIndex(); // define center point about 300m from that location final double lat = 37.774277; final double lon = -122.404744 ; // one user within 400 meters IS NOT blocked by bart Query query = Query.fromQL( "select * where NOT blockedBy.name='bart' and location within 400 of " + lat + "," + lon); Results listResults = em.searchCollection( em.getApplicationRef(), "users", query ); assertEquals( 1, listResults.size() ); // one user within 400 meters IS blocked by bart query = Query.fromQL( "select * where blockedBy.name='bart' and location within 400 of " + lat + "," + lon); listResults = em.searchCollection( em.getApplicationRef(), "users", query ); assertEquals( 1, listResults.size() ); } }