3

我遇到了以下问题:我试图从用户的手机中获取 x [英里/公里] 内的用户。我正在使用谷歌应用引擎的数据存储 api,我不知道是什么问题。问题是,当我使用迭代获取记录时——出现一个错误,告诉我我不能在组合过滤器中使用不同的属性。

    package com.linkedlive.business;

    import java.io.IOException;
    import java.util.Iterator;

    import javax.servlet.http.*;

    import org.json.JSONArray;
    import org.json.JSONObject;

    import com.biomedica.server.geolocation.GeoLocation;
    import com.biomedica.server.searchtools.SearchForGeolocEntitiy;
    import com.google.appengine.api.datastore.DatastoreService;
    import com.google.appengine.api.datastore.DatastoreServiceFactory;
    import com.google.appengine.api.datastore.Entity;
    import com.google.appengine.api.datastore.KeyFactory;

    @SuppressWarnings("serial")
    public class Venue extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        this.doPost(req, resp);

    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {

        DatastoreService datastore =
      DatastoreServiceFactory.getDatastoreService();


        String cmd=req.getParameter("cmd");
        if(cmd.equals("venuenearby"))
        {
            GeoLocation geo=new GeoLocation();
            SearchForGeolocEntitiy search=new
    SearchForGeolocEntitiy("accounts");// this is a class that i created to set the
    query filters see bellow
            // get request parameters
            float lat=Float.valueOf(req.getParameter("lat"));
            float lng=Float.valueOf(req.getParameter("lng"));
            float rad=Float.valueOf(req.getParameter("rad"));
            // calculate the distance


            Iterable<Entity>
    ent=search.GetJSONForEntitiyNearByUsingBounds(lat,
    lng,geo.getGeoLocationBounds(lat, lng, rad) );
            Iterator<Entity> i=ent.iterator();
            JSONObject json=new JSONObject();
            JSONArray injson=new JSONArray();
            json.put("result", "venuenearby");

            while(i.hasNext())
            {
                try {
                    JSONObject j=new JSONObject();
                    Entity t=i.next();
                    j.put("key",
    KeyFactory.keyToString(t.getKey()));
                    j.put("userid",
    t.getProperty("userid"));
                    j.put("filepath",
    t.getProperty("filepath"));
                    injson.put(j);
                } catch (NullPointerException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            json.put("body",injson);
            resp.getWriter().write(json.toString());
        }


    }
    }





///////////////////////////////////////////////////////////////////////////////
////////////////////
//////////////////////////  SearchForGeolocEntitiy      
////////////////////////////////////


    package com.biomedica.server.searchtools;

    import java.lang.reflect.Array;
    import java.util.Arrays;

    import com.biomedica.server.geolocation.GeoLocation;
    import com.google.appengine.api.datastore.DatastoreService;
    import com.google.appengine.api.datastore.DatastoreServiceFactory;
    import com.google.appengine.api.datastore.Entity;
    import com.google.appengine.api.datastore.PreparedQuery;
    import com.google.appengine.api.datastore.Query;
    import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
    import com.google.appengine.api.datastore.Query.Filter;
    import com.google.appengine.api.datastore.Query.FilterOperator;
    import com.google.appengine.api.datastore.Query.FilterPredicate;
    import com.google.appengine.api.datastore.Query.CompositeFilter;

     public class SearchForGeolocEntitiy {
     private String EntitiyName;
     private Query q;

     public SearchForGeolocEntitiy(String name)
    {
        EntitiyName=name;
        q=new Query(name);

    }
    public Iterable<Entity> GetJSONForEntitiyNearBy(double lang,double
    lat,double rad,int max_result)
    {
        DatastoreService datastore =
    DatastoreServiceFactory.getDatastoreService();
        // decleeraing filter object




                Filter filter_min_lngt=new
    FilterPredicate("lng", FilterOperator.GREATER_THAN, lang-rad);
                Filter filter_max_lngt=new
    FilterPredicate("lng", FilterOperator.LESS_THAN, lang+rad);
                Filter filter_min_lat=new
    FilterPredicate("lat", FilterOperator.GREATER_THAN, lat-rad);
                Filter filter_max_lat=new
    FilterPredicate("lat", FilterOperator.LESS_THAN, lat+rad);

                Filter filter_lng=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lngt,filte
    r_max_lngt));
                Filter filter_lat=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lat,filter
    _max_lat));


                Filter filter=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_lng,filter_lat
     ));

                q.setFilter(filter);
                PreparedQuery pq = datastore.prepare(q);


                return pq.asIterable();

    }
    public Iterable<Entity> GetJSONForEntitiyNearByUsingSSID(String
    EntityName,String entityID,String SSID)
    {
        DatastoreService datastore =
    DatastoreServiceFactory.getDatastoreService();
        // decleeraing filter object


            Filter filter_entityID=new FilterPredicate(EntityName,
    FilterOperator.EQUAL, entityID);

                Filter filter_min_lngt=new
    FilterPredicate("lng", FilterOperator.EQUAL, SSID);

                Filter filter=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_entityID,filte
    r_min_lngt));

                q.setFilter(filter);

                PreparedQuery pq = datastore.prepare(q);
                return pq.asIterable();


    }
    public Iterable<Entity> GetJSONForEntitiyNearByUsingBounds(float
    lng,float lat,GeoLocation.GeoLocationBoundry bound)
    {
        DatastoreService datastore =
    DatastoreServiceFactory.getDatastoreService();

        Filter filter_min_lngt=new FilterPredicate("lng",
    FilterOperator.LESS_THAN, bound.lng1);
        Filter filter_max_lngt=new FilterPredicate("lng",
    FilterOperator.LESS_THAN, bound.lng2);
        Filter filter_min_lat=new FilterPredicate("lat",
    FilterOperator.GREATER_THAN, bound.lat1);
        Filter filter_max_lat=new FilterPredicate("lat",
    FilterOperator.LESS_THAN, bound.lat2);

        Filter filter_lng=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lngt,filte
    r_max_lngt));
        Filter filter_lat=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_min_lat,filter
    _max_lat));


        Filter filter=new
    CompositeFilter(CompositeFilterOperator.AND,Arrays.asList(filter_lng,filter_lat
    ));

        q.setFilter(filter);

        PreparedQuery pq = datastore.prepare(q);


        return pq.asIterable();
    }
    }
4

1 回答 1

1

您遇到了数据存储的限制。不等式过滤器只能在一个属性上。

https://developers.google.com/appengine/docs/java/datastore/queries#Restrictions_on_Queries

解决此问题的最简单方法是使用 Search API。否则,您需要构建自己的类似地理散列的机制来在不使用多个不等式过滤器的情况下在一个范围内进行搜索。

于 2012-08-17T01:48:53.160 回答