Как отфильтровать командный курсор в mongodb - PullRequest
0 голосов
/ 02 декабря 2018

Я довольно плохо знаком с базами данных NoSQL.У меня трудности с простой проблемой

У меня есть база данных с датами, которые являются строками.Я хочу отфильтровать свою коллекцию, чтобы получить элементы, дата которых превышает определенную дату.Чтобы решить эту проблему, я преобразовал свои строковые даты в объекты даты и добавил их как поле, используя метод агрегата $ addFields.

collection.aggregate([{
"$addFields": {
  "CA": {
    "$convert": {
      "input": {
        "$substr": ["$headers.Date", 5, 20]
      },
      "to": "date"
    }
  }
}}])

Сначала я попробовал приведенный выше код, и он работает.Есть поле «CA» с объектами даты, но я хотел отфильтровать их, используя поиск и фильтр, но так как это был командный курсор, методы были недоступны.Вот почему я попробовал приведенный ниже код и не сработал.Это в основном модифицированная версия кода, над которой я добавил $ filter

collection.aggregate([{
  "$filter": {
     "input": {
        "$addFields": {
           "CA": {
              "$convert": {
                 "input": {
                    "$substr": ["$headers.Date", 5, 20]
                 },
                 #"$headers.Date"
                 "to": "date"
              }
           }
        }
     },
     'as': 'db',
     "cond": {
        "$lt": ["$db.CA", datetime.now()]
     }
  }}])

Редактировать: По запросу я добавил образец элемента ниже

{'_id': ObjectId('e27'),
 'body': "Body",
 'subFolder': 'notes_inbox',
 'mailbox': 'bass-e',
 'filename': '450.',
 'headers': {'X-cc': '',
  'From': 'XXX@XX.com',
  'Subject': 'Re: information',
  'X-Folder': '\\Notes inbox',
  'Content-Transfer-Encoding': '7bit',
  'X-bcc': '',
  'To': 'x.bass@y.com',
  'X-Origin': 'Bass-E',
  'X-FileName': 'ebass.nsf',
  'X-From': 'Miel Sim',
  'Date': 'Tue, 14 Nov 2000 08:22:00 -0800 (PST)',
  'X-To': 'Eric Bass',
  'Message-ID': '<6884142.1075854677416.JavaMail.evans@thyme>',
  'Content-Type': 'text/plain; charset=us-ascii',
  'Mime-Version': '1.0'}}

1 Ответ

0 голосов
/ 02 декабря 2018

Вы можете использовать $ filter , когда вам нужно отфильтровать вложенный массив, в вашем случае, так как у вас есть одно значение, вы можете просто использовать $ match , попробуйте:

db.collection.aggregate([
    {
        "$addFields": {
            "CA": {
                "$convert": {
                "input": {
                    "$substr": ["$headers.Date", 5, 20]
                },
                    "to": "date"
                }
            }
        }
    },
    {
        $match: {
            CA: { $lt: ISODate() } // or datetime.now()
        }
    }
])

Если вы не хотите добавлять новое поле, вы можете использовать оператор $ expr :

db.collection.aggregate([
    {
        $match: {
            $expr: {
                $lt: [ { $convert: { input: { "$substr": ["$headers.Date", 5, 20] }, to: "date" } }, ISODate() ]
            }
        }
    }
])
...