猫鼬按条件对填充字段进行排序

时间:2019-06-16 07:41:28

标签: node.js mongodb mongoose database-design

我有两个模式

vehicle模式:

const VehicleSchema = new Schema({
title: {
    type: String,
    required: true
},
price: {
    type: Number,
    required: true
},
);
VehicleSchema.virtual('promotions', {
   ref: 'Promotion',
   localField: '_id',
   foreignField: 'vehicle',
   justOne: true
});
export default mongoose.model('Vehicle', VehicleSchema);

Promotion架构:

const PromotionSchema = new Schema({
    start_at: {
        type: Date,
        required: true
    },
    end_at: {
        type: Date,
        required: true
    },
    vehicle: {
        type: Schema.Types.ObjectId,
        ref: 'Vehicle'
    },
    amount:{
        type:Number,
        required:true
    },
});
export default mongoose.model('Promotion', PromotionSchema);

每个vehicle具有多个Promotion且促销活动处于活动状态({start_at少于Date.now,而end_at则超过Date.now)< / p>

1-我需要让所有具有一次促销的车辆(现在处于活动状态)并按start_at

对其进行排序

2-是否可以添加名称为is_promotion的虚拟字段并将其设置为true(如果促销活动有效)?

注意:某些Vehicle可能没有任何Promotion

2 个答案:

答案 0 :(得分:3)

您可以使用$lookup

按车辆ID进行$ lookup促销,以获取条件,排序和限制以获取最新促销。

$addFields添加is_promotion字段。

VehicleSchema.aggregate([
  {"$lookup":{
    "from":"Promotion",
    "let":{"_id":"$_id"},
    "pipeline":[
      {"$match":{
        "start_at":{"$lt":Date.now},
        "end_at":{"$gt":Date.now},
        "$expr":{"$eq":["$vehicle","$$_id"]}
      }},
      {"$sort":{"start_at":-1}},
      {"$limit":1}
    ],
    "as":"activepromotion"
  }},
  {"$addFields":{
    "is_promotion":{"$gt":[{"$size":"$activepromotion"},0]}
  }}
])

答案 1 :(得分:-1)

#尝试获取我们的VehicleSchema的start_at,然后使用find()在所有PromotionSchema的VehicleSchema字段中进行搜索。#

// FactorySmart.cpp

#include <iostream>
#include <vector>
#include <memory>

enum AnimalSpecies { dog, cat };

class Animal
{
public:
  virtual void makeSound() = 0;
};

class Dog : public Animal
{
public:
  void makeSound() { std::cout << "woof" << "\n\n"; }
};

class Cat : public Animal
{
public:
  void makeSound() { std::cout << "meow" << "\n\n"; }
};

class AnimalFactory
{
public:
  static std::unique_ptr<Animal> makeAnimal(AnimalSpecies animalSpecies);
};

std::unique_ptr<Animal> AnimalFactory::makeAnimal(AnimalSpecies animalSpecies)
{
  if (animalSpecies == AnimalSpecies::dog)
  {
    std::unique_ptr<Animal> dog = std::make_unique<Dog>();
    return(dog);
  }
  else if (animalSpecies == AnimalSpecies::cat)
  {
    std::unique_ptr<Animal> cat = std::make_unique<Cat>();
    return(cat);
  }
  else
  {
    std::cout << "error in AnimalFactory::makeAnimal(), animalSpecies = " << animalSpecies << " does not seem to be valid" << "\n\n";
    return(nullptr);
  }  
}

int main(void)
{
  std::vector<std::unique_ptr<Animal>> animals;

  std::unique_ptr<Animal> dog = AnimalFactory::makeAnimal(AnimalSpecies::dog);
  animals.push_back(std::move(dog));

  std::unique_ptr<Animal> cat = AnimalFactory::makeAnimal(AnimalSpecies::cat);
  animals.push_back(std::move(cat));

  for (auto &animal : animals)
  {
    animal->makeSound();
  }  

  return(0);
}