MongoDB / Mongoose एक विशिष्ट तिथि में क्वेरी?


141

क्या किसी विशिष्ट तिथि के लिए क्वेरी करना संभव है?

मैंने मोंगो कुकबुक में पाया कि हम इसे एक तिथि सीमा के लिए क्वेरी की तरह कर सकते हैं जैसे:

db.posts.find({"created_on": {"$gte": start, "$lt": end}})

लेकिन क्या यह एक विशिष्ट तिथि के लिए संभव है? यह काम नहीं करता है:

db.posts.find({"created_on": new Date(2012, 7, 14) })

जवाबों:


212

यदि आपके द्वारा DB में सहेजी गई तारीखें बिना समय के हैं (केवल वर्ष, माह, दिन)।

संभावना है कि आपके द्वारा सहेजी गई तारीखें थीं new Date(), जिसमें समय घटक शामिल हैं। उन समय को क्वेरी करने के लिए आपको एक तिथि सीमा बनाने की आवश्यकता होती है जिसमें एक दिन में सभी क्षण शामिल होते हैं।

db.posts.find( //query today up to tonight
  {"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

29
याद रखें कि दिनांक () फ़ंक्शन में, महीने का तर्क 0 पर नहीं, 1 से गिनना शुरू करता है। दूसरी ओर, दिन 1 पर गिनना शुरू करते हैं ... विवरण
मार्क स्टोसबर्ग

यह उन दोनों को कठिन कोड के बजाय अगली तारीख पाने के लिए _ 1 दिन करना बेहतर नहीं है?
राजू

2
इस विधि ठीक काम करता है अगर तारीख इस तरह संग्रहीत किया जाता है है: >> "तिथि": ISODate ( "2016-01-04T14: 07: 17.496Z")
संतोष

क्या आपके पास अपने महीने और दिनांक स्विच नहीं हैं। तिथियां प्रारूप होना चाहिए: yyyy, dd, MM
thethakuri

123

... 5+ साल बाद, मैं दृढ़ता से इसके बजाय दिनांक-एफएनएस का उपयोग करने का सुझाव देता हूं

import endOfDayfrom 'date-fns/endOfDay'
import startOfDay from 'date-fns/startOfDay'

MyModel.find({
  createdAt: {
    $gte: startOfDay(new Date()),
    $lte: endOfDay(new Date())
  }
})

Moment.js का उपयोग कर हम में से उन लोगों के लिए

const moment = require('moment')

const today = moment().startOf('day')

MyModel.find({
  createdAt: {
    $gte: today.toDate(),
    $lte: moment(today).endOf('day').toDate()
  }
})

महत्वपूर्ण: सभी क्षण परस्पर हैं !

tomorrow = today.add(1, 'days')काम नहीं करता है क्योंकि यह भी उत्परिवर्तित करता है today। कॉलिंग से moment(today)उस समस्या का निराकरण प्रतिरूपण द्वारा होता है today


13
मैं .startOf('day').hours (0) .minutes (0)। सेकंड (0) के बजाय का उपयोग करने का सुझाव देता हूं । तो पहली पंक्ति होगी:var today = moment().startOf('day')
जिम ज्यूर्ट्स

2
यदि हम moment(today)ऑब्जेक्ट को क्लोन करने के लिए उपयोग कर रहे हैं , तो एक और उपाय है:var tomorrow = today.clone().add(1, 'days')
johntellsall

1
@johntellsall निहित के बजाय स्पष्ट क्लोनिंग, एक ही परिणाम लेकिन शायद वास्तव में पढ़ने के लिए आसान!
पियर-ल्यूक गेंड्रेउ

1
वैकल्पिक रूप से, मैं के लिए निम्नलिखित सुझाव है कि सकता है $lt: moment(today).endOf('day')। अगले दिन से वास्तविक परिणामों को शामिल करने से रोकने के लिए।
ज्रेडन

1
मेरे लिए moment(today).endOf('day')के समय के साथ एक ही दिन देता है: 23:59:59.999। इसलिए वास्तव में उपयोग करने के लिए अधिक सही लगता है $lte, अन्यथा उस विशेष समय पर वस्तुओं की अनदेखी की जाएगी।
leonprou

11

हाँ, दिनांक ऑब्जेक्ट दिनांक और समय का संकलन करता है, इसलिए केवल दिनांक मान के साथ तुलना करने से काम नहीं होता है।

आप बस $ का उपयोग कर सकते हैं जहां ऑपरेटर जावास्क्रिप्ट बूलियन अभिव्यक्ति के साथ अधिक जटिल स्थिति को व्यक्त करने के लिए :)

db.posts.find({ '$where': 'this.created_on.toJSON().slice(0, 10) == "2012-07-14"' })

created_onडेटाइम फ़ील्ड है और 2012-07-14निर्दिष्ट तिथि है।

दिनांक YYYY-MM-DD प्रारूप में बिल्कुल होना चाहिए ।

नोट:$where संयम से उपयोग करें , इसके प्रदर्शन निहितार्थ हैं।


10

आपने कोशिश की है:

db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

आप जिस समस्या को चलाने जा रहे हैं, वह यह है कि तारीखों को मोंगो में टाइमस्टैम्प के रूप में संग्रहीत किया जाता है। इसलिए, एक तारीख से मिलान करने के लिए आप इसे टाइमस्टैम्प से मिलान करने के लिए कह रहे हैं। आपके मामले में मुझे लगता है कि आप एक दिन (यानी एक विशिष्ट तिथि को 00:00 से 23:59 तक) का मिलान करने की कोशिश कर रहे हैं। यदि आपकी तिथियां बिना समय के संग्रहीत हैं, तो आपको ठीक होना चाहिए। अन्यथा, अपनी तिथि को उसी दिन समय की सीमा के रूप में निर्दिष्ट करने का प्रयास करें (जैसे। प्रारंभ = 00: 00, अंत = 23: 59) यदि gte काम नहीं करता है।

इसी तरह का सवाल


1
इसमें निर्दिष्ट तिथि से कम उम्र के सभी तत्व शामिल होंगे, जो शायद वह नहीं था जो ओपी चाहता था। अन्य उत्तरों की तरह "lt" विकल्प जोड़ने पर विचार करें।
बेनसोवर

मुझे लगता है कि अगर आपके पास $gteइसके बजाय gteबेहतर होगा।
जैक खाली

यह पहले से ही अधिक सही ढंग से ऊपर उत्तर दिया गया है, लेकिन यह मुझे यह जानकर परेशान कर रहा था कि मेरा उत्तर बंद था, इसलिए मैंने इसे प्रश्न के लिए सही होने के लिए अद्यतन किया। अरे, 4 साल हो गए। lol
माइकल डी जॉनसन

6

आप विशिष्ट दिन से परिणाम प्राप्त करने के लिए एपीआई विधि के लिए निम्नलिखित दृष्टिकोण का उपयोग कर सकते हैं:

# [HTTP GET]
getMeals: (req, res) ->
  options = {}
  # eg. api/v1/meals?date=Tue+Jan+13+2015+00%3A00%3A00+GMT%2B0100+(CET)
  if req.query.date?
    date = new Date req.query.date
    date.setHours 0, 0, 0, 0
    endDate = new Date date
    endDate.setHours 23, 59, 59, 59
    options.date =
      $lt: endDate
      $gte: date

  Meal.find options, (err, meals) ->
      if err or not meals
        handleError err, meals, res
      else
        res.json createJSON meals, null, 'meals'

1

हमारे डेटाबेस में डुप्लिकेट किए गए डेटा से संबंधित एक समस्या थी, जिसमें एक दिनांक फ़ील्ड के साथ कई मान होते थे जहां हम 1 थे। मैंने सोचा कि मैं जिस तरह से हमने संदर्भ के लिए समस्या का समाधान किया है।

हमारे पास संख्यात्मक "मान" फ़ील्ड और "दिनांक" फ़ील्ड के साथ "डेटा" नामक एक संग्रह है। हमारे पास एक प्रक्रिया थी जिसके बारे में हमने सोचा था कि यह बेकार है, लेकिन प्रति सेकंड 2 x मूल्यों को दूसरे रन में जोड़ दिया गया:

{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}

हमें केवल 2 में से 1 रिकॉर्ड चाहिए, इसलिए db को साफ करने के लिए जावास्क्रिप्ट का सहारा लेना पड़ा। हमारा प्रारंभिक दृष्टिकोण परिणामों के माध्यम से पुनरावृत्त होने वाला था और किसी भी क्षेत्र को सुबह 6 बजे से सुबह 11 बजे के बीच हटा दिया गया था (सभी डुप्लिकेट सुबह में थे), लेकिन कार्यान्वयन के दौरान, एक बदलाव किया। यहाँ इसे ठीक करने के लिए उपयोग की गई स्क्रिप्ट है:

var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
    var datum = data.next();
    var rdate = datum.date;
    // instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
    if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
       if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
           print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
       }
       else {
           print("Removing " + datum._id);
           db.data.remove({ "_id": datum._id});
       }
    }
    else {
       found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
    }
}

और फिर इसके साथ भाग गया mongo thedatabase fixer_script.js

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.