2016-08-24 8 views
0

私のケースを簡単に説明しようとしましょう。私はMongoDBの初心者です。私はCouchDBから離れて自分の選択肢を探そうとしています。

サンプル文書は、この(短縮、単純化された)ように見えることがあります。

{ 
    exp: [ 
    { 
     isCurrent: true, 
     name: 'Name 1' 
    }, 
    { 
     isCurrent: false, 
     name: 'Name 2' 
    } 
    ] 
} 

インデックスは次のようになります。

{ 
    "exp.name":1, 
    "exp.foo":1, 
    "exp.bar":1 
}, { 
    partialFilterExpression:{ "exp.isCurrent": {$eq: true}} 
} 

はい、「foo」と「バー」は冗長に見えるんが、彼ら私の現在のインデックスの一部であり、私は彼らが結果を歪めるとは思わない。

「現在の」「行」だけをインデックス化することです。今、私が次のようなクエリを使用した場合:

{$and:[{"exp.name":"Name 2"},{"exp.isCurrent":true}]} 

...上記のドキュメントは依然としてクエリを満たしています。どうして?さらに重要なことは、私は自分がしたいことをどうすればいいのですか?それも可能ですか?見た目は単純ですGoogle BigQueryは、同じレコードのフィールドに$andを適用します(このシナリオではNOの結果を返します)。

また、私の "isCurrent:true"は常に[0]です。これを利用してクエリを正確かつ効率的に書くことはできますか?

答えて

1

exp [1] .name = "Name 2"とexp [0] .isCurrentが真であるために示されたドキュメントです。

partialFilterExpressionは、exp.isCurrentがtrueの場合にmongodbはドキュメントのインデックスを作成しません。あなたがそれを見つけるのを止めることはありません。

あなたがexp [i] .name = "name 2"とexp [i]を返すことを確認したい場合は、isCurrent同時に真である(iがnに0することができます)、これを試してみてください。

db.test.find({"exp":{$elemMatch:{$and:[{"name":"Name 1"},{"isCurrent":true}]}}}) 

あなたは、配列の正確最初の要素たいクエリは、あなたがこのようにそれを行うことができる場合:

db.test.find({$and:[{"exp.0.name":"Name 1"},{"exp.0.isCurrent":true}]}) 

希望します

+0

残念ながら、私は多くの行を持っており、dbはシーケンシャルスキャンを行っていますので、私はテストできません。インデックスは明らかにクエリの要件を満たしていないためです。 "isCurrent = true"を持つ "exp"だけを含むように異なる方法でインデックスを作成する方法はありますか?私の現在の 'partialFilterExpression'は、私がやろうとしていることでは不十分と思われます。 – wpfwannabe

+0

埋め込みドキュメントを返すだけですか?私はCouchbaseにマップリダクションがあることを知っています。たとえドキュメントが埋め込まれていても、ビューを生成してフラットにします。 mongodbがそれを手伝ってくれるかどうかは分かりません。おそらく、mongodbのmapreduce機能を見てください。 mongodbが3.0より新しい場合(2.xバージョンはデータベース全体をスキャンします)、$ elemMatchを使用したこの問合せでは、explain()機能を使用して問合せ中にどの索引が使用されているかを確認できます。 –

0

$とは、2つ以上の式(expression1、expression2など)の配列に対して論理AND演算を実行し、配列のすべての式を満たす文書を選択するためです。ここから。 https://docs.mongodb.com/manual/reference/operator/query/and/

欲望の結果を得るには、リターニングされた結果に対していくつかの縮小またはマップまたはフィルタを使用することができます。たとえば、次のように入力します。

coll.find({"exp.name":"Name 2"}); 

結果にフィルタを適用します。

また、スキーマを変更しようとしている可能性があります。この

{name1: {current: true, name: "test"}, name2: {current: false, name: "another"}} 

のような個別のオブジェクトへのすべてのデータを取得し、今、あなたはこのことができます

coll.find({'name2.current': false}); 

希望を照会することができます。

関連する問題