Запрос Mongoose по вложенному документу возвращает массив другого вложенного документа, используя проекцию - PullRequest
0 голосов
/ 12 января 2019

Обновление: Я ищу ответ, который работает в проекции mongodb: https://docs.mongodb.com/manual/reference/method/db.collection.findOne/#definition

Я пытаюсь отфильтровать запрос по вложенному документу, используя проекцию, чтобы он возвращал только определенный массив. Но при фильтрации результат также включает в себя массив другого поддокумента. Когда я не фильтрую, он возвращает только найденный документ.

Я пробовал разные варианты фильтрации, включая и исключая позиционные элементы, но не могу получить желаемый результат.

Схема Мангуста

const stationSchema = new mongoose.Schema({

  mac: String,
  stationName: String,
  syncReadings: Boolean,
  temperature: Array,
  humidity: Array,
  measures: [{
  date: Date,
  temperature: Number,
  humidity: Number
  }],
  lastUpdated: Date

});

// Define user schema
var userSchema = mongoose.Schema({

    local            : {
        email        : String,
        password     : String
    },
    facebook         : {
        id           : String,
        token        : String,
        name         : String,
        email        : String
    },
    twitter          : {
        id           : String,
        token        : String,
        displayName  : String,
        username     : String
   },
   google           : {
        id           : String,
        token        : String,
        email        : String,
        name         : String
   },
   apiKey: String,
   stations : [stationSchema]

   },  
   {
       usePushEach: true 
   }
);

Обработчик API

app.get('/api/stations/:stationName/measures', function(req, res, next) {

  var user = {
    apiKey: req.user.apiKey
  }

  const query = {
        apiKey: user.apiKey,
        stations.stationName': req.params.stationName
  }

  const options = {
        'stations.measures': 1
  }

  User.findOne(query, options)
  .exec()
  .then(stations => {       
        res.status(200).send(stations)
  })
  .catch(err => {
    console.log(err);
    res.status(400).send(err);
  })

});

Под одним пользователем есть две станции:

[
    {
        "_id": "5c39c99356bbf002fb092ce9",
        "stations": [
            {
                "stationName": "livingroom",
                "mac": "5C:CF:7F:77:12:FB",
                "_id": "5c39c9ab56bbf002fb092cea",
                "lastUpdated": "2019-01-12T11:07:01.802Z",
                "syncReadings": false,
                "measures": [],
                "humidity": [],
                "temperature": [
                    {
                        "date": "2019-01-12T11:07:01.802Z",
                        "temperature": "20"
                    }
                ]
            },
            {
                "stationName": "office",
                "mac": "5C:CF:7F:77:12:FC",
                "_id": "5c39cacdce4ac903123f0150",
                "measures": [],
                "humidity": [],
                "temperature": []
            }
        ]
    }
]

вызов API

http://localhost:8080/api/stations/livingroom/measures

Результат

{
    "_id": "5c39c99356bbf002fb092ce9",
    "stations": [
        {
            "measures": []
        },
        {
            "measures": []
        }
    ]
}

Пробные варианты проецирования

 const options = {
   'stations.measures': 1
 }

 const options = {
   'stations.$.measures': 1
 }

 const options = {
   'stations.$': 1,
   'stations.$.measures': 1
 }

 const options = {
   'stations.$': 1,
   'stations.measures': 1
 }

Что я делаю не так?

1 Ответ

0 голосов
/ 12 января 2019

попробуйте использовать только эти параметры запроса, и после этого вы получите пользователя с запрошенной станцией.

var user = {
    apiKey: req.user.apiKey
  }

  const query = {
        apiKey: user.apiKey,
        'stations.stationName': req.params.stationName
  }

тогда сделайте это

    User.findOne(query, options)
      .exec()
      .then(stations => {      

        for(let station of stations){
           if(station.measures[1]){ // here it is the index  

           res.status(200).send(stations);
        }
    }


})
  .catch(err => {
    console.log(err);
    res.status(400).send(err);
  }) 

на самом деле в mongoose вы не можете запрашивать вложенные документы, вам нужен такой подход. Вы можете запрашивать вложенные документы только так, как вы сделали

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...