2017-08-23 12 views
1

を行った後、FETCHでヌルフィルタ用モンゴクエリ、なぜ<a href="https://docs.mongodb.com/manual/tutorial/query-for-null-fields/" rel="nofollow noreferrer">Mongo Documentation</a>によるとIXSCAN

{ item : null }クエリはどちらかが値nullであるか、それがitem フィールドが含まれていない itemフィールドを含む文書が一致します。

私はこのためのドキュメントを見つけることはできませんが、私の知る限り、どちらの場合は、(値がnullであるか、フィールドが欠落している)nullとしてインデックスに格納されています。私はdb.orders.createIndex({item: 1})、その後db.orders.find({item: null})をすれば

だから、私はIXSCANは、どちらかが値であるnullまたはそのitemフィールド、およびドキュメントのみが含まれていないitemフィールドが含まれているすべてのドキュメントを見つけることを期待します。

を実行した後にがのステージでfilter: {item: {$eq: null}}を実行するのはなぜですか。フィルタリングする必要がある文書はありますか?

{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "temp.orders", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "item" : { 
       "$eq" : null 
      } 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "filter" : { 
       "item" : { 
        "$eq" : null 
       } 
      }, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "keyPattern" : { 
        "item" : 1 
       }, 
       "indexName" : "item_1", 
       "isMultiKey" : false, 
       "isUnique" : false, 
       "isSparse" : false, 
       "isPartial" : false, 
       "indexVersion" : 1, 
       "direction" : "forward", 
       "indexBounds" : { 
        "item" : [ 
         "[null, null]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ ] 
    }, 
    "serverInfo" : { 
     "host" : "Andys-MacBook-Pro-2.local", 
     "port" : 27017, 
     "version" : "3.2.8", 
     "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" 
    }, 
    "ok" : 1 
} 

私は多分undefined値はnullとしてインデックス付けになるだろうと思ったが、簡単な実験はこれを除外:

> db.orders.createIndex({item: 1}) 
{ 
    "createdCollectionAutomatically" : true, 
    "numIndexesBefore" : 1, 
    "numIndexesAfter" : 2, 
    "ok" : 1 
} 
> db.orders.insert({item: undefined}) 
WriteResult({ "nInserted" : 1 }) 
> db.orders.find({item: {$type: 6}}).explain() 
{ 
    "queryPlanner" : { 
     "plannerVersion" : 1, 
     "namespace" : "temp.orders", 
     "indexFilterSet" : false, 
     "parsedQuery" : { 
      "item" : { 
       "$type" : 6 
      } 
     }, 
     "winningPlan" : { 
      "stage" : "FETCH", 
      "filter" : { 
       "item" : { 
        "$type" : 6 
       } 
      }, 
      "inputStage" : { 
       "stage" : "IXSCAN", 
       "keyPattern" : { 
        "item" : 1 
       }, 
       "indexName" : "item_1", 
       "isMultiKey" : false, 
       "isUnique" : false, 
       "isSparse" : false, 
       "isPartial" : false, 
       "indexVersion" : 1, 
       "direction" : "forward", 
       "indexBounds" : { 
        "item" : [ 
         "[undefined, undefined]" 
        ] 
       } 
      } 
     }, 
     "rejectedPlans" : [ ] 
    }, 
    "serverInfo" : { 
     "host" : "Andys-MacBook-Pro-2.local", 
     "port" : 27017, 
     "version" : "3.2.8", 
     "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" 
    }, 
    "ok" : 1 
} 

答えて

1

ヌル平等マッチ述語(例えば{"a.b": null})のためのセマンティクスはフィールドので、十分に複雑です索引スキャンだけでは正確な結果を得るには不十分なサブ文書が含まれている可能性があります。もはやに一致すると考え なかった:

https://jira.mongodb.org/browse/SERVER-18653?focusedCommentId=931817&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-931817によれば、サーバの

バージョン2.6.0は、文書が{[]}であるよう、ヌル平等 マッチ述語の意味を変更しましたクエリ述部{"ab":null}(以前の バージョンのサーバーでは、この文書はこの0​​述語の一致と見なされました)。これは、互換性に関する2.6のノートに記載されています。 の「null比較」セクションの下にあります。

キーパターン{"a.b":1}のインデックスの場合、この文書{a:[]} はインデックスキー{"":null}を生成します。 {a:null}のような他のドキュメントと空のドキュメント{ }もインデックスキー{"":null}を生成します。 結果として、述語{"a.b":null}を持つクエリがこのインデックスを使用する場合、 クエリシステムは、関連付けられたドキュメントが述語と一致しないかどうかをインデックスキー{"":null}から判断できません。その結果、EXACT境界の代わりに のINEXACT_FETCH境界が割り当てられるため、 FETCHステージがクエリ実行ツリーに追加されます。

追加説明:

  1. 文書{}インデックスキー{ "":ヌル}キーパターンのインデックスの生成{ "a.b":1}。
  2. ドキュメント{a:[]}は、キーパターン{"a.b":1}のインデックスに対してインデックスキー{"":null}も生成します。
  3. 文書{}はクエリ{"a.b":null}と一致します。
  4. 文書{a:[]}がクエリ{"a.b":null}と一致しません。したがって

、クエリ{「AB」:ヌル}鍵 パターン{「AB」:1}のインデックスによって回答されるドキュメントをフェッチしなければならない保証するために、述語、 を再確認ドキュメント{}が結果セット に含まれ、ドキュメント{a:[]}が結果セットに含まれていないことを確認してください。

関連する問題

 関連する問題