MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

MongoDB एकत्रीकरण ढांचे के साथ पहले ऑर्डर व्युत्पन्न की गणना करें

db.collection.aggregate(
    [
      {
        "$addFields": {
          "indexes": {
            "$range": [
              0,
              {
                "$size": "$time_series"
              }
            ]
          },
          "reversedSeries": {
            "$reverseArray": "$time_series"
          }
        }
      },
      {
        "$project": {
          "derivatives": {
            "$reverseArray": {
              "$slice": [
                {
                  "$map": {
                    "input": {
                      "$zip": {
                        "inputs": [
                          "$reversedSeries",
                          "$indexes"
                        ]
                      }
                    },
                    "in": {
                      "$subtract": [
                        {
                          "$arrayElemAt": [
                            "$$this",
                            0
                          ]
                        },
                        {
                          "$arrayElemAt": [
                            "$reversedSeries",
                            {
                              "$add": [
                                {
                                  "$arrayElemAt": [
                                    "$$this",
                                    1
                                  ]
                                },
                                1
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  }
                },
                {
                  "$subtract": [
                    {
                      "$size": "$time_series"
                    },
                    1
                  ]
                }
              ]
            }
          },
          "time_series": 1
        }
      }
    ]
)

ऐसा करने के लिए हम संस्करण 3.4+ में उपरोक्त पाइपलाइन का उपयोग कर सकते हैं। पाइपलाइन में, हम $addFields पाइपलाइन चरण। दस्तावेज़ करने के लिए "time_series" के तत्वों के सूचकांक की सरणी जोड़ने के लिए ऑपरेटर, हमने समय श्रृंखला सरणी को भी उलट दिया और इसे क्रमशः $range और $reverseArray ऑपरेटर्स

हमने यहां ऐरे को उलट दिया है क्योंकि तत्व p . पर स्थित है सरणी में हमेशा स्थिति पर तत्व से बड़ा होता है p+1 जिसका अर्थ है कि [p] - [p+1] <0 और हम $multiply का इस्तेमाल नहीं करना चाहते यहाँ। (संस्करण 3.2 के लिए पाइपलाइन देखें)

आगे हम $zipped इंडेक्स एरे के साथ टाइम सीरीज़ डेटा और एक subtract लागू किया। कोड> $map . का उपयोग करके परिणामी सरणी के लिए अभिव्यक्ति ऑपरेटर।

फिर हम $slice शून्य/कोई नहीं को छोड़ने का परिणाम सरणी से मूल्य और परिणाम को फिर से उलट दिया।

3.2 में हम $unwind का इस्तेमाल कर सकते हैं खोलने . के लिए ऑपरेटर हमारे सरणी और $ द्वारा उपसर्ग किए गए पारंपरिक "पथ" के बजाय दस्तावेज़ को ऑपरेंड के रूप में निर्दिष्ट करके सरणी में प्रत्येक तत्व की अनुक्रमणिका शामिल करें ।

पाइपलाइन में अगला, हमें $group हमारे दस्तावेज़ और $push का उपयोग करें इस तरह दिखने वाले उप-दस्तावेजों की एक सरणी वापस करने के लिए संचायक ऑपरेटर:

{
    "_id" : ObjectId("57c11ddbe860bd0b5df6bc64"),
    "time_series" : [
        { "value" : 10, "index" : NumberLong(0) },
        { "value" : 20, "index" : NumberLong(1) },
        { "value" : 40, "index" : NumberLong(2) },
        { "value" : 70, "index" : NumberLong(3) },
        { "value" : 110, "index" : NumberLong(4) }
    ]
}

अंत में आता है $project मंच। इस चरण में, हमें $map ऑपरेटर $group . में नई गणना की गई सरणी में प्रत्येक तत्व के लिए अभिव्यक्ति की एक श्रृंखला लागू करने के लिए मंच।

यहाँ क्या चल रहा है $map . के अंदर (देखें $नक्शा लूप के रूप में) में अभिव्यक्ति:

प्रत्येक उप-दस्तावेज़ के लिए, हम मान . निर्दिष्ट करते हैं $let का इस्तेमाल करके वेरिएबल को फ़ील्ड करें परिवर्तनीय ऑपरेटर। फिर हम इसे सरणी में अगले तत्व के "मान" फ़ील्ड के मान से घटाते हैं।

चूंकि सरणी में अगला तत्व वर्तमान इंडेक्स प्लस वन का तत्व है, इसलिए हमें केवल $arrayElemAt ऑपरेटर और एक साधारण $add वर्तमान तत्व की अनुक्रमणिका और 1 .

$subtract व्यंजक एक ऋणात्मक मान लौटाता है, इसलिए हमें मान को -1 . से गुणा करना होगा $multiply का इस्तेमाल करके ऑपरेटर।

हमें $filter की भी आवश्यकता है परिणामी सरणी क्योंकि यह अंतिम तत्व है कोई नहीं या शून्य . इसका कारण यह है कि जब वर्तमान तत्व अंतिम तत्व होता है, $subtract वापसी कोई नहीं क्योंकि अगले तत्व का सूचकांक सरणी के आकार के बराबर है।

db.collection.aggregate([
  {
    "$unwind": {
      "path": "$time_series",
      "includeArrayIndex": "index"
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "time_series": {
        "$push": {
          "value": "$time_series",
          "index": "$index"
        }
      }
    }
  },
  {
    "$project": {
      "time_series": {
        "$filter": {
          "input": {
            "$map": {
              "input": "$time_series",
              "as": "el",
              "in": {
                "$multiply": [
                  {
                    "$subtract": [
                      "$$el.value",
                      {
                        "$let": {
                          "vars": {
                            "nextElement": {
                              "$arrayElemAt": [
                                "$time_series",
                                {
                                  "$add": [
                                    "$$el.index",
                                    1
                                  ]
                                }
                              ]
                            }
                          },
                          "in": "$$nextElement.value"
                        }
                      }
                    ]
                  },
                  -1
                ]
              }
            }
          },
          "as": "item",
          "cond": {
            "$gte": [
              "$$item",
              0
            ]
          }
        }
      }
    }
  }
])

एक अन्य विकल्प जो मुझे लगता है कि कम कुशल है map_reduce विधि।

>>> import pymongo
>>> from bson.code import Code
>>> client = pymongo.MongoClient()
>>> db = client.test
>>> collection = db.collection
>>> mapper = Code("""
...               function() {
...                 var derivatives = [];
...                 for (var index=1; index<this.time_series.length; index++) {
...                   derivatives.push(this.time_series[index] - this.time_series[index-1]);
...                 }
...                 emit(this._id, derivatives);
...               }
...               """)
>>> reducer = Code("""
...                function(key, value) {}
...                """)
>>> for res in collection.map_reduce(mapper, reducer, out={'inline': 1})['results']:
...     print(res)  # or do something with the document.
... 
{'value': [10.0, 20.0, 30.0, 40.0], '_id': ObjectId('57c11ddbe860bd0b5df6bc64')}

आप सभी दस्तावेज़ पुनः प्राप्त कर सकते हैं और numpy.diff . का उपयोग कर सकते हैं इस तरह व्युत्पन्न वापस करने के लिए:

import numpy as np


for document in collection.find({}, {'time_series': 1}):
    result = np.diff(document['time_series']) 


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Node.js . के माध्यम से MongoDB में डालें

  2. मोंगोडब:विशिष्ट दस्तावेज प्राप्त करने का सबसे अच्छा तरीका और फिर बाकी

  3. MongoDB फ़ील्ड को स्ट्रिंग से ISODate में सरणी में कनवर्ट करें

  4. मोंगोड, मैक ओएस एक्स - चेतावनी को सीमित करता है

  5. MongoDB GeoJSON वस्तु, विकृत ज्यामिति से भू कुंजी नहीं निकाल सकता है? पॉलीगॉन टाइप करते समय