2016-10-26 10 views
0

私はpymongoを使用しています。私のコレクションの文書は次のようになります。MongoDB:値が特定の順序で存在する場合、json配列からデータを取得する

{ 
    train_name: <Train1> 
    train_number: <#> 
    details: [ 
     { 
     station_name: <station1> 
     arrives: <time> 
     departs: <time> 
     distance_travelled: <distance> 
     halt: <> 
     } 

    { 
     station_name: <station2> 
     arrives: <time> 
     departs: <time> 
     distance_travelled: <distance> 
     halt: <> 
     } 

    { 
     station_name: <station3> 
     arrives: <time> 
     departs: <time> 
     distance_travelled: <distance> 
     halt: <> 
     } 

    ] 

このデータベースにクエリを送信して、2つのステーション間で利用可能な電車を検索します。つまり、ユーザーは 'ソース'ステーションと 'デスティネーションステーション'を提供し、 'ソース'と 'デスティネーション'の間で利用可能なすべての列車を返すクエリが必要です

このサンプルドキュメントから、 'Train1' その結果、ユーザが提供する場合:

  1. ソース - "STATION1"
    先 - "station2"
  2. ソース - "STATION1"
    先 - "station3"
- "station2"
先 - "STATION1"
  • ソース - "station3"
    先 - "STATION1"

    1. ソースを:ユーザが提供している場合は

      'Train1は' 復帰すべきではありません

    要するに、値が特定の順序でjsonリストに存在する場合のみ、結果を照会して取得したいと考えています。

    はこれまでのところ、私はこの

    cursor = db.trains.find({"detail.station_name": {"$all": [source, destination]}}, 
               {"train_name": True, "train_no": True, "_id": False}) 
    

    を持っている。しかしその注文を尊重していません。それは、その順序に関係なく、「ソース」と「デスティネーション」の両方を持つすべての電車名を私に与えます。

    私は私の質問ではっきりと願っています。私はmongodbに新しいです。だから、どんな助けにも感謝します。

    ありがとうございました。

  • +0

    こんにちは、あなたのデータに列車の方向がありません。つまり、最初の例(source:station1)と2番目の例(destination:station1)の違いは何ですか?いくつかの情報を追加するか、ドキュメントに[schema](https://docs.mongodb.com/manual/data-modeling/)を変更して方向を示すことができます。また、あなたの質問は本質的に "私に駅名が' station1'と 'station2'と一致するすべての駅名を見つけて、' train_name'と 'train_no'フィールドだけを返すように求めています。 –

    +0

    私の質問に混乱があったら申し訳ありません。上記の例の文書では、 'station1'は旅の開始地点、 'station3'は 'Train1'の旅路 'ends'です。したがって、データは「詳細」リストが既に正しいoderでソートされています。私が必要とするのは、 'station1'(任意の発信元とすることができる)と 'station3'(任意の送信先の駅)の間を走るならば、この列車名を得ることだけです。私は指示された方向に文書のスキーマをどのように変更できるかわかりません。あなたはちょっとそれを詳しく教えてもらえますか?ありがとう。 –

    答えて

    3

    したがって、データは「詳細」リストは既に正しいoderでソートされています。

    details値がソートされた正しい順序にすでにある場合は、使用してクエリを実行できます。

    あなたが初の放送局名が station1し、任意である、すべての列車を探す探している
    db.trains.find( 
          {$and:[ 
          {"details.0.station_name":"station1"},   
          {"details.station_name":"station2"} 
          ]}, 
          {"train_name":1, train_number:1, _id:0} 
    ); 
    

    を他のステーションはstation2 'を含む。

    上記のことから、配列のインデックスを扱うユースケース/アプリケーションによっては、必ずしも理想的ではない場合があります。つまり、最初の注文番号以外の注文番号を常に知っているとは限りません。

    私は指示された方向に文書のスキーマをどのように変更できるか分かりません。それで少し詳しく説明できますか?

    頻繁に使用されるクエリを活用して最適化するために、さまざまな方法があります。data modelingがあります。ドメイン専門家として、あなたはこの決定を下すのに最適な人物です。ただし、以下の は、代替例を示します。

    あなたは簡単に開始/終了ステーションを照会するsourceStationdestinationStationためのフィールドを含めることができます

    { 
        sourceStation: { 
         id: 001, 
         name: "station1" 
        }, 
        destinationStation:{ 
         id: 010, 
         name: "station3" 
        }, 
        details: [ 
         { station_name: "station1", 
         ... }, 
         { station_name: "station2", 
         ... }, 
         { station_name: "station3", 
         ...} 
        ], 
        train_name: "Train1", 
        train_no: 88, 
        arrives: <time>, 
        departs: <time>, 
        distance_travelled: <distance> 
    } 
    

    それとも、ブレークオフ可能性の旅を別の文書に旅の細かさのために:

    { 
        _id: ObjectId(...), 
        sourceStation: { 
         id: 001, 
         name: "station1" 
        }, 
        destinationStation:{ 
         id: 009, 
         name: "station2" 
        }, 
        train_name: "Train1", 
        train_no: 88, 
        arrives: "0900", 
        departs: "0910", 
        distance_travelled: "3kms" 
    }, 
    
    { 
        _id: ObjectId(...), 
        sourceStation: { 
         id: 009, 
         name: "station2" 
        }, 
        destinationStation:{ 
         id: 010, 
         name: "station3" 
        }, 
        train_name: "Train1", 
        train_no: 88, 
        arrives: "0930", 
        departs: "0940", 
        distance_travelled: "4kms" 
    } 
    

    も参照してくださいData Model Examples and Patternsより多くのインスピレーションのために。

    私はmongodbを初めて使っています。だから、どんな助けにも感謝します。

    MongoDB Universityの無料オンラインコースに登録することをおすすめします。特に、M101の開発者コースでは、スキーマの設計とクエリを扱います。

    +0

    詳細な説明をいただきありがとうございます。あなたが投稿したこのクエリを調べています。 db.trains.find( {$や:[ { "details.0.station_name": "STATION1"}、{ "details.station_name": "station2"} ]}、{ "train_name":1 、train_number:1、_id:0} );ここでは、ステーション1は最初のステーションでなければならないと仮定していますが、そうでない場合があります。私は 'station1'と 'station2'の間を走っていると私に列車を与えるクエリを探しています。 (ここでは、ステーション1とステーション2は必ずしも始点と終点である必要はありません) –

    +0

    ステーション2はステーション1の後に来る必要があります。クエリを作成できるのであれば私を助けてください。そうでなければ、提案したように他のスキーマオプションを調べます。ありがとう。 –

    +0

    理想的なソリューションは、スキーマモデルを再設計することです。もちろん、廃止予定の 'map-reduce'や' $ where'を使用することもできますが、NoSQLスキーマの柔軟性の適切な概念を使用せず、パフォーマンスを罰することになります。また、[サポートされているMongoDBドライバ](https://docs.mongodb.com/ecosystem/drivers/)のいずれかを使用して配列インデックスを取得することもできます。 –

    関連する問題