6

時間がある場合(たとえば、火曜日の午後4時24分)、一連のビジネスから現在開いているすべてのビジネスを選択できるようにしたいと思います。

  • 毎日、すべてのビジネスの営業時間と閉店時間があります
  • ビジネスが毎時00、15、30、45分のマークでのみ開閉できると仮定しましょう
  • 毎週同じスケジュールを想定しています。
  • 私は、データのスペース要件ではなく、特定の時間に営業している一連のビジネスをすばやく検索できることに最も興味があります。
  • 念のために言っておきますが、ある日の午後11時に開店し、翌日の午前1時に閉店する人もいます。
  • 休日は関係ありません-私はこれらを別々に扱います

単一の時間/曜日のタプルでどのビジネスが開いているかをすばやく把握できるように、これらの開店/閉店時間を保存する最も効率的な方法は何ですか?

Python、SOLR、mysqlを使用しています。SOLRでクエリを実行できるようにしたいと思います。しかし率直に言って、私はどんな提案や代替案にもオープンです。

4

7 に答える 7

8

一度に1週間だけを確認する場合は、すべての開始/終了時間を正規化して、週の開始からの分数、たとえば日曜日の0時間に設定できます。ストアごとに、[startTime、endTime、storeId]の形式のタプルをいくつか作成します。(日曜日の深夜にまたがる時間の場合、2つのタプルを作成する必要があります。1つは週の終わりに、もう1つは週の初めに始まります)。このタプルのセットは、startTimeとendTimeの両方でインデックス付けされます(たとえば、前処理するツリーを使用して)。タプルはそれほど大きくするべきではありません。1週間に1万分しかなく、2バイトに収まります。この構造は、適切なインデックスを持つMySQLテーブル内で適切であり、情報が変更されたときのレコードの絶え間ない挿入と削除に対して非常に回復力があります。あなたのクエリは単に「

情報があまり頻繁に変更されず、ルックアップを非常に高速にしたい場合は、考えられるすべてのクエリを事前に解決して、結果をキャッシュできます。たとえば、1週間に672時間の期間しかありません。Brandon Rhodesのソリューションのように、それぞれに開店時間と閉店時間のリストが含まれているビジネスのリストを使用すると、1週間に15分ごとに繰り返し、誰が営業しているかを把握し、ルックアップテーブルに回答を保存できます。またはメモリ内リスト。

于 2009-04-22T00:25:59.623 に答える
5

別の回答者が言及したビットマップフィールドは非常に効率的ですが、ビット数とフィールドのデザインを毎回算術的に増やす必要があるため、30分または15分時間を処理できるようにする場合は面倒になります一致しなければならない新しい解像度に遭遇します。

代わりに、値を日時としてリスト内に保存してみます。

openclosings = [ open1, close1, open2, close2, ... ]

次に、組み込みの「bisect」モジュールでPythonの「bisect_right()」関数を使用して、高速のO(log n)時間で、クエリ時間が「適合する」場所を見つけます。次に、返されるインデックスを確認します。偶数(0、2、4 ...)の場合、時間は「閉店」時間と次の「開店」時間の間にあるため、ショップは閉店します。代わりに、二等分インデックスが奇数(1、3、5 ...)の場合、時間は開店時間と閉店時間の間に到着し、ショップは営業しています。

ビットマップほど高速ではありませんが、解像度について心配する必要はありません。また、これほどエレガントな別のO(log n)ソリューションを考えることはできません。

于 2009-04-22T00:08:07.357 に答える
4

あなたは、SOLRを使用していて、ストレージを気にせず、ルックアップを高速にしたいと言っています。次に、オープン/クローズタプルを格納する代わりに、必要な粒度のレベル(15分)で、開いている時間のブロックごとにエントリにインデックスを付けます。エンコーディング自体には、累積時間:分だけを使用できます。

たとえば、月曜日の午後4時から5時まで営業している店舗では、[40:00、40:15、40:30、40:45]にインデックス付きの値が追加されます。月曜日の午後4時24分のクエリは40:15に正規化されるため、そのストアドキュメントと一致します。

これは一見非効率に見えるかもしれませんが、インデックス作成の速度とスペースに対する一定のペナルティは比較的小さいです。そして、検索を可能な限り高速にします。

于 2009-04-22T01:13:48.807 に答える
3

申し訳ありませんが、簡単な答えはありませんが、90年代後半の会社の開発チームのマネージャーとして、この問題の解決を任されていたので、大変でした。

比較的小さなビットマスク(168ビット= 1時間に1回)で実行できるのは、毎週の時間ではありません。トリックは、毎週火曜日に休業するビジネスです。

ビットマスクから始めて、例外フィールドに移動することは、私が今まで見た中で最高の解決策です。

于 2009-04-21T23:52:58.673 に答える
1

Solrインデックスでは、各ビジネスを時間のある1つのドキュメントとしてインデックス付けするのではなく、1週間の間にすべてのビジネスのすべての「小売セッション」にインデックスを付けます。

たとえば、ジョーのコーヒーが月曜から土曜の午前6時から午後9時まで開いていて、日曜が閉まっている場合、それぞれが「開」と「閉」の2つのインデックス付きフィールドを持つ6つの異なるドキュメントにインデックスを付けます。単位が15分間隔の場合、値の範囲は0〜7 * 24*4です。ビジネスごとに一意のIDがある場合は、これを各ドキュメントに保存して、セッションをビジネスにマッピングできるようにします。

次に、Solrで範囲検索を実行できます。

開く:[* TO N]および閉じる:[N + 1TO *]

ここで、Nは、現在の時刻が該当するN番目の15分間隔で計算されます。たとえば、水曜日の午前10時10分である場合、クエリは次のようになります。

開く:[*から112]そして閉じる:[113から*]

別名「水曜日の午前10時以前に開始し、水曜日の午前10時15分以降に終了するセッションを検索する」

場所や製品など、他の基準を検索に含める場合は、各セッションドキュメントでもこれにインデックスを付ける必要があります。これは少し冗長ですが、インデックスが大きくなければ問題にはなりません。

于 2009-04-22T14:18:22.507 に答える
0

データをうまく制御できれば、@Sebastianのような簡単な解決策がわかります。[time = startTime、storeId]および[time = endTime、storeId]の形式でタプルを作成する場合を除いて、タプルの作成に関するアドバイスに従ってください。次に、これらをリストに並べ替えます。ストアが開いているかどうかを確認するには、次のようなクエリを実行します。

select storeId
from table
where time <= '@1'
group by storeId
having count(storeId) % 2 == 1

これを最適化するために、時間tごとにルックアップテーブルを作成し、tで開いているストアを格納し、tとt + 1の間のストアの開閉(tの任意のグループ化)を行うことができます。

ただし、これには保守が難しいという欠点があります(重複する開閉は、より長い開閉期間にマージする必要があります)。

于 2009-04-22T01:18:43.833 に答える
0

ユニークなオープン/クローズ時間の組み合わせがいくつあるかを見ましたか?それほど多くない場合は、一意の組み合わせの参照テーブルを作成し、各ビジネスに対する適切なエントリのインデックスを保存します。次に、参照テーブルを検索して、それらのインデックスを持つビジネスを見つけるだけです。

于 2009-04-22T02:03:30.980 に答える