2

アプリケーションにフィルター機能を実装していますが、CouchDB でのビューの書き込みに問題があります。SQL では、これは複数の結合を持つステートメントになります。CouchDB で複数の結合を置き換える方法。この記事では、単一結合について説明しています: http://www.cmlenz.net/archives/2007/10/couchdb-joins。ただし、このアプローチを複数の結合に拡張する方法は明らかではありません。

オブジェクトに多数のプロパティがあり、各プロパティに個別のフィルターを設定できるとします。簡単にするために、2 つのプロパティしかないと仮定しましょう。それを解決できれば、おそらく任意の数のプロパティに拡張できます。

私のアプリケーションは、一連の AND フィルターをサポートする必要があります。たとえば、場所が ("Seattle", "New York") AND start-epoch >= 1336608413 のすべてのセッションを検索します。また、フィルター設定を保持する必要もあります。

SQL には、Session と Filter という 2 つのテーブルがあります。次に、Session テーブルと Filter テーブルの間のフィルター条件ごとに 1 つの結合を行い、フィルター処理されたすべてのセッションを取得します。

Session Table
location    start-epoch    
Seattle     1336608413     

Filter Table
Name        Value
location    Seattle
location    New York
start-epoch 1336608413     


Query:
select * 
from Session s 
where exists (select 1 from Filter f where f.name = 'location' and f.value = s.location)
     and exists (select 1 from Filter f on f.name = 'start-epoch' and s.start-epoch >= f2.value)

CouchDB では:

{"type":"session", "location":"Seattle", "start-epoch":1336608413}

次に、フィルターをモデル化し、ビューを作成する方法は?

フィルターは次のようになります。

{"type":"filter", "location":["Seattle", "New York"], "start-epoch":1336608413}

次に、ビューをどのように記述しますか?

これを CouchDB 内で実現したいと考えています。FilteredSessions というビューを作成し、Couch への 1 回の http 呼び出しでフィルター処理されたセッションを取得したいと考えています。理由は、5 つの異なるクライアント (iOS、Android、Silverlight、Ruby on Rails、および Windows 8) があり、ロジックを 5 回も書き直したくないためです。sqlite を使用すると、「FilteredView」というビューを作成してそれを実現できます。map reduce に同等のものを書きたいと思います。

4

3 に答える 3

1

うーん...何が必要か正確にはわかりませんが、私が理解したのは次のとおりです。セッションを呼び出しているデータのコレクションが 1 つあり、フィルターを呼び出している別のデータのコレクションがあります。次に、セッションからデータの別のコレクションを組み立てたいと考えていますが、フィルター データを使用してセッションから特定のデータを選択します。それが正しければ、それを行うにはいくつかの方法があります。

30 ほどのセッション ドキュメントがあるとします。それぞれに、location と start-epoch の 2 つのプロパティがあります。例えば:

{
 "_id"         : "f80hqwfe8nfaodnia9dgs8n9",
 "location"    : "Seattle",
 "start-epoch" : "1336608413",
 "type"        : "session"
}

または...

{
 "_id"         : "f8fsdnio345235aodnia9dgs8n9",
 "location"    : "New York",
 "start-epoch" : "1236630174",
 "type"        : "session"
}

次に、次のようないくつかのフィルターがあります。

{
 "_id"         : "f80hqwfe8nfaodnia9dgs8n9",
 "location"    : "New York",
 "type"        : "filter"
}

または...

{
 "_id"         : "f80hqwfe8nfaodnia9dgs8n9",
 "start-epoch" : "1336608413",
 "type"        : "filter"
}

すべてのセッションを 1 つのビューにまとめることができます。

"sesssions": {
  "map": "function (doc) {
    if (doc.type === "session") {
      emit(doc.start-epoch, doc);
    }
}"

次に、すべてのフィルターを 1 つのビューにまとめます (これはその場で更新できます)。

"filters": {
  "map": "function (doc) {
    if (doc.type === "filter") {
      emit(doc.type, doc);
    }
}"

そのため、nodejs で最終的な「ビュー」を組み立てます。データベースのフィルタービューにリクエストを送信するか、必要に応じて新しいフィルターを作成し、それをフィルターやフィルターなどの変数に保存します。次に、データベースのセッション ビューをもう一度呼び出して、そのデータをセッションなどの変数に取り込みます。

ここでちょっと補足。ビューを呼び出して (couch が var ビューに返した json オブジェクトを保存したとします)、view.rows をセッション変数に保存する必要があります。これにより、次のようなセッションの配列が得られます。

[
 {
  "_id"         : "f80hqwfe8nfaodnia9dgs8n9",
  "location"    : "Seattle",
  "start-epoch" : "1336608413",
  "type"        : "session"
 },
 {
  "_id"         : "f8fsdnio345235aodnia9dgs8n9",
  "location"    : "New York",
  "start-epoch" : "1236630174",
  "type"        : "session"
 }
]

それからただする

var myFinalView = sessions.forEach(function (session) {
  if (filter.location !== session.location) {
    // session.splice or delete session
  }
  return;
})

そして、myFinalView が必要な JSON オブジェクトになります。それが理にかなっていることを願っています。必要に応じて詳しく教えてください。

于 2012-05-13T00:41:52.920 に答える
0
var sessions = [];
var filters = [];

function(doc) {
  if (doc.type === 'session') {
    sessions.push(doc);
  }
  if (doc.type === 'filter') {
    filters.push(doc);
  }
  emit(filters.length, filters);
  emit(sessions.length, sessions);
}

私はこれらのエミットを関数の終わりの下に引き出そうとしましたが、それは CouchDB を混乱させたようです。これにより、フィルターとセッションがコレクションに「コンパイル」されます。その「コンパイル」がいつ完了するかを知る良い方法があれば、次のステップは、フィルターをループしてから、フィルターを適用するセッションを forEach でループすることです。

この課題を共有していただきありがとうございます。これは CouchDB の限界を押し上げます。私たちはこれを理解できることを願っています、それは可能であるべきです。

于 2012-05-19T07:03:14.700 に答える
0

これが私の考えです。map 関数では、セッション ドキュメントとフィルター ドキュメントの両方を発行します。次に、list 関数を使用してマップ出力を列挙し、永続化されたフィルターとセッションを読み取り、フィルター処理を行います。

于 2012-05-25T20:53:21.130 に答える