2016-11-18 11 views
0

は、だから私はこの権利のようなものを持っているが、今http://codepen.io/anon/pen/bBgVOL複数のパラメータでデータをフィルタリングする最も効率的な方法は?

これは、緯度/経度、その後、私のコントローラにすることを渡す私を返すGETのAJAX呼び出しに渡し、場所を取ります。

@RequestMapping(value = "/rentals", method = RequestMethod.GET) 
    public String rentResults(@RequestParam(value = "page", required = false) Integer pageNumber, @RequestParam(value = "lat", required = false) String lat, @RequestParam(value = "lng", required = false) String lng, @RequestParam(value = "rad", required = false) String rad, Map model) { 
     int total = 25; 

     if (pageNumber == null) { 
      pageNumber = 1; 
     } else { 
      pageNumber = (pageNumber - 1) * total + 1; 
     } 

     List<ForRent> rentals = new ArrayList(); 

     int count; 
     if (lat == null && lng == null && rad == null) { 
      rentals = forRentDao.getRentalsByPage(pageNumber, total); 
      count = forRentDao.getNumOfRentals(); 
     } else { 
      count = forRentDao.RentalRadiusCount(lat, lng, rad); 
      rentals = forRentDao.RentalRadius(lat, lng, rad, pageNumber, total); 

      String latParam = "&lat=" + lat; 
      String lngParam = "&lng=" + lng; 
      String radParam = "&rad=" + rad; 

      model.put("latParam", latParam); 
      model.put("lngParam", lngParam); 
      model.put("radParam", radParam); 
     } 

     int page; 

     if (count % total == 0) { 
      page = (count/total); 
     } else { 
      page = 1 + (count/total); 
     } 

     List<Integer> pages = new ArrayList(); 
     for (int i = 1; i <= page; i++) { 
      pages.add(i); 
     } 

     model.put("pages", pages); 

     model.put("rentals", rentals); 
     boolean rent = true; 
     model.put("rent", rent); 

     return "rent"; 

    } 

JS

function initMap() { 

       var input = /** @type {!HTMLInputElement} */(
         document.getElementById('address')); 


       var autocomplete = new google.maps.places.Autocomplete(input); 

        }; 


    $('#searchRadius').on('click', function (e) { 

     var lati; 
     var lng; 
     var address = $('#address').val(); 
     var rad = $('#radius').val(); 
     var select = document.getElementById('sel'); 
     var choice = select.value; 



     e.preventDefault(); 


     $.ajax({ 
      type: "GET", 
      url: "http://www.mapquestapi.com/geocoding/v1/address?key=&location=" + address, 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader("Accept", "application/json"); 
       xhr.setRequestHeader("Content-type", "application/json"); 
      }, 
      success: function postForm(response) { 
       lati = response.results[0].locations[0].latLng.lat; 
       lng = response.results[0].locations[0].latLng.lng; 

       if (rad == null) { 
        rad = '10'; 
       } 

       console.log(lati, lng, rad); 

       var data = JSON.stringify({ 
        lat: lati, 
        lng: lng, 
        rad: rad 
       }); 

       if (choice == 1) { 

        $.ajax({ 
         url: contextRoot + "/map/radius", 
         type: "POST", 
         data: data, 
         dataType: 'json', 
         beforeSend: function (xhr) { 
          xhr.setRequestHeader("Accept", "application/json"); 
          xhr.setRequestHeader("Content-type", "application/json"); 
         }, 
         success: function (data, status) { 
          console.log(data); 
          window.location = contextRoot + "/rent/rentals?lat=" + data.lat + "&lng=" + data.lng + "&rad=" + data.rad; 

         }, 
         error: function (data, status) { 
          alert("bad api call"); 
          console.log(status); 
         } 
        }); 
       } 
      }, 
      error: function (data, status) { 
       console.log(data.errors); 
      }} 
     ); 
    }); 

を(はい、私はそれが厄介である知っている)ので、今それは緯度/経度/半径パラメータを指定せずにレンタルのリストを返します。いずれか、またはそれが適用されたパラメータでリストを返します。 。

私はこの約5~10以上のパラメータを追加する必要があります(例:http://codepen.io/anon/pen/QGdjoB用)

私は私のコントローラは、今、最も可能性の高い文句を言わない作業をセットアップし、私はよので、今後大きな頭痛の種になります持っている方法パラメータに基づいてif/else文をたくさん必要とします。私は現時点でSQLクエリを使用してデータをフィルタリングしています。すべてのデータを返してメモリにフィルタリングする方が良いでしょうか、このコントローラの応答をより良く/より効率的に設定する方法がありますか?

ありがとうございます!

答えて

0

データベースは検索とフィルタリングに最適化されます。これが主な使用例です。さらに、データベースにはJavaが持たないインデックスにアクセスできます。さらに、データベースは、Javaで試すものよりも高速な検索を実装する可能性があります。データベースの検索の実装では、たとえば並行性が使用されます。

完全に白黒ではありません。たぶん、データベースのハードウェアが非常に遅いです。その状況では、おそらくJavaアプリケーションサーバーがフィルタリングを高速化できます。多分、データベースは機械的なハードドライブ上にあるので、ランダムアクセスでは速度が遅いです(これはインデックスを利用すると悪くなります...しかし、Javaには全くインデックスがありません)。

の場合はなので、作業をデータベースにプッシュすることをおすすめします。


もちろん、検索条件とフィルタ条件がリレーショナルデータベースモデルに適していない場合もあります。 「古い車が存在するすべての車を見つける」などのデータ依存関係のフィルタ基準を検討してください。これはちょっとハムしてしまいました(私は遅いと思いますが)。データベースは、それが設計された仕事だけで高速です。

パフォーマンスが実際にの場合は、それをベンチマークします。それを両方の方法で試して、測定を行います。

パフォーマンスがの場合、の問題がない場合は、どのコードを維持するのが難しいのかを自分で確認してください。パラメータ化された動的な方法でSQLクエリを作成すると、かなり醜いことがあります。しかし、Javaでのデータ構造の操作もかなり醜いことがあります。

0

私のコントローラを設定している方法は、ほとんどの場合動作しません。また、パラメータに基づいてif/else文がたくさん必要になるため、今後の大きな頭痛になります。

あなたは間違いなく

  .addInUnlessNull("supplier.id", idList) 
      .addEqUnlessNull("id", input.templateId) 
      .addEqIf(!request.includeDeleted(), "isDeleted", false) 
      .addEqUnlessNull("branch.id", input.branchId) 
      .addEqUnlessNull("supplier.id", input.supplierId) 

私は休止状態を使用していますが、これはあまりにも、プレーンなSQLに作ることができることに私自身のシンプルなインタフェースであるとして、これは問題ではありません:それは、私は5つの基準で検索をした方法です。ちょうど何かのような

MyQuery addEqUnlessNull(String path, @Nullable Object value) { 
    if (value != null) { 
     sql.append(" AND " + path + " = ?"); 
     args.append(value); 
    } 
    return this; 
} 

する必要があります。 SQLインジェクションに注意してください。クエリで使用されるパーツは決してユーザーから来てはなりません。すべての安全でない入力は、SQLパラメーターとして使用するか、少なくとも適切にエスケープする必要があります。

ホイールを改造する代わりに、querydslまたはそれに類するものを見てください。 JavaのPlain SQLは古くなっています。私の主なポイントは、繰り返し操作ごとに、メソッドを書く場合は1行しか必要ないということです。


データベース内のすべての処理は、通常、最も簡単で、おそらく最も高速です。あなたは簡単に重要な基準にインデックスを追加することができます。インデックスは書き込みを遅くし、テーブルあたり最大でも1つのインデックスしか使用できないことに注意してください。

私はあなたがそれを稼働させていくつかの使用統計を得る前に、より多くの最適化を気にしません。それらがなければ、まれにしかあなたの時間を無駄にすることはありません。

リスト全体が長すぎない場合は、別の方法で行うこともできます。 - データベースでのフィルタリング。 - アプリケーション内に何もありません。 - クライアントで並べ替えとページング(つまり、結果をページに属するものに減らす)。

オプションで、クライアントで追加のフィルタリングを行うことができます。

関連する問題