3

次の問題が発生しています。ユーザーの携帯電話からx[マイル/km]以内にいるユーザーを取得しようとしています。Google App Engine用のデータストア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

データストアの制限に達しています。不等式フィルターは、1つのプロパティにのみ存在できます。

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

これを回避する最も簡単な方法は、SearchAPIを使用することです。それ以外の場合は、複数の不等式フィルターを使用せずに範囲内を検索するための独自のジオハッシュのようなメカニズムを構築する必要があります。

于 2012-08-17T01:48:53.160 に答える