Запрос Mongodb в массиве в полях строки даты - PullRequest
0 голосов
/ 06 августа 2020

У меня есть документ в mongodb и я хотел бы иметь только свечи со временем с 02.01.2010 по 05.01.2010, но я не думаю, что это нравится: Спасибо

{
    "_id" : ObjectId("5f25916e771c501cf1c040be"),
    "instrument" : "AUD_USD",
    "granularity" : "D",
    "candles" : [ 
        {
            "complete" : true,
            "volume" : 5,
            "time" : "2009-12-31T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.89815",
                "h" : "0.89850",
                "l" : "0.89800",
                "c" : "0.89825"
            }
        }, 
        {
            "complete" : true,
            "volume" : 330,
            "time" : "2010-01-02T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.89820",
                "h" : "0.89944",
                "l" : "0.89725",
                "c" : "0.89881"
            }
        }, 
        {
            "complete" : true,
            "volume" : 15449,
            "time" : "2010-01-03T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.89885",
                "h" : "0.91376",
                "l" : "0.89398",
                "c" : "0.91278"
            }
        }, 
        {
            "complete" : true,
            "volume" : 17119,
            "time" : "2010-01-04T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.91282",
                "h" : "0.91751",
                "l" : "0.90936",
                "c" : "0.91196"
            }
        }, 
        {
            "complete" : true,
            "volume" : 16740,
            "time" : "2010-01-05T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.91188",
                "h" : "0.92180",
                "l" : "0.90998",
                "c" : "0.91984"
            }
        }, 
        {
            "complete" : true,
            "volume" : 18321,
            "time" : "2010-01-06T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.91972",
                "h" : "0.92676",
                "l" : "0.91605",
                "c" : "0.91753"
            }
        }, 
        {
            "complete" : true,
            "volume" : 18262,
            "time" : "2010-01-07T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.91765",
                "h" : "0.92582",
                "l" : "0.91243",
                "c" : "0.92521"
            }
        }, 
        {
            "complete" : true,
            "volume" : 1,
            "time" : "2010-01-08T22:00:00.000000000Z",
            "ask" : {
                "o" : "0.92521",
                "h" : "0.92521",
                "l" : "0.92521",
                "c" : "0.92521"
            }
        }
    ]
}

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Не могли бы вы подтвердить, что значение candles.time хранится как дата, а не как строка? Мне пришлось отредактировать ваши образцы данных и обернуть каждую дату с помощью ISODate, чтобы это работало.

Я думаю, вы спрашиваете, как отфильтровать поле массива candles только для свечей между двумя датами. Вам нужно будет использовать $filter следующим образом:

https://mongoplayground.net/p/i9DvUTmtY2R

db.collection.aggregate({
  $addFields: {
    candles: {
      $filter: {
        input: "$candles",
        as: "candle",
        cond: {
          $and: [
            {$gte: ["$$candle.time", {$toDate: "2010-01-02"}]},
            {$lt: ["$$candle.time", {$toDate: "2010-01-05"}]}
          ]
        }
      }
    }
  }
});

Вот пример, оставляющий ваши демонстрационные данные как есть и пытающийся их преобразовать к дате на фильтре. Как вы увидите, это не удается из-за лишнего 0 в строке времени. https://mongoplayground.net/p/onMZu8Brj9V

Чтобы использовать updateMany для преобразования поля «time» из строки в дату, выполните в оболочке следующее:


db.COLLECTION.updateMany(
  {},
  [{$set: {
    'candles': {$map: {
      input: '$candles',
      as: 'candle',
      in: {$mergeObjects: [
        '$$candle',
        {
          time: {$toDate: {$concat: [
            // Trim trim the extra 0
            {$substrCP: ['$$candle.time', 0, 28]},
            'Z'
          ]}
        }}
      ]}

    }}
  }}]
)

Я использовал $ map, поскольку он не отображается, вы можете получить доступ к текущему значению метода элемента массива array.$.field. Обязательно обновите схему, чтобы новые значения больше не сохранялись в виде строк. После преобразования исходный ответ должен работать.

0 голосов
/ 06 августа 2020
from_date = ISODate("2010-01-02T00:00:00Z"); day begin
to_date   = ISODate("2010-01-05T23:59:59Z"); day end

$time: {"$gte": from_date, "$lt": to_date}

Полный запрос для возврата всех элементов между этими двумя датами будет выглядеть так:

db.your_collection.find({"time":{ "$gte": from_date, "$lt": to_date) }});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...