是否可以使用猫鼬直接查询子文档? [英] Is it possible to query subdocuments directly using mongoose?

查看:74
本文介绍了是否可以使用猫鼬直接查询子文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个User模型和一个Post模型.在这种情况下,用户的帖子会很多;用户将是父级,而邮政将是子级.可以直接查询帖子吗?

例如,如果我想做类似的事情

app.get('/post/search/:query', (req,res) => {
       Posts.find({title: req.params.query }, (err,post) => {
            res.send(JSON.stringify(post))
       })
})

或者必须要做的事情:

app.get('/post/search/:query',(req,res) => {

  let resultsFromQuery = [];
  User.find({'post.title':req.params.query'}, (err,user) => {
       user.posts.forEach((post) => {
           if(post.title === req.params.query){
               resultsFromQuery.push(post); 
           }
       })
  })
res.send(JSON.stringify(resultsFromQuery))

})

这是我的架构.

用户架构(父)

const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    PostSchema = require('./post.js');

let UserSchema = new Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    posts: [PostSchema]
})

module.exports = mongoose.model('User',UserSchema);

发布架构(子级)

const mongoose = require('mongoose'),
    Schema = mongoose.Schema;

let PostSchema = new Schema({
    title: {
        type: String
    },
    description: {
        type: String
    },
    image: {
        type: String
    },
    original_poster: {
        id: {
            type: String,
            required: true
        },
        username: {
            type: String,
            required: true
        }
    },
    tags: {
        type: [String],
        required: true
    }
})

module.exports = PostSchema;

这是示例文档

db.users.find({username:'john'}))的结果

{
    "_id" : ObjectId("5a163317bf92864245250cf4"),
    "username" : "john",
    "password" : "$2a$10$mvE.UNgvBZgOURAv28xyA.UdlJi4Zj9IX.OIiOCdp/HC.Cpkuq.ru",
    "posts" : [
        {
          "_id" : ObjectId("5a17c32d54d6ef4987ea275b"),
            "title" : "Dogs are cool",
            "description" : "I like huskies",
            "image" : "https://media1.giphy.com/media/EvRj5lfd8ctUY/giphy.gif",
            "original_poster" : {
                "id" : "5a163317bf92864245250cf4",
                "username" : "john"
            },
            "tags" : [
                "puppies",
                "dogs"
            ]
        }
    ],
    "__v" : 1
}

解决方案

是的,您可以直接从用户模型中找到帖子标题.像波纹管一样

User.find({"posts.title": "Cats are cool"}, (err, users) => {
  if(err) {
    // return error
  }
  return res.send(users)
})

这将返回具有所有帖子的用户,而不仅仅是匹配的帖子标题.因此,仅返回匹配的帖子标题可以使用$位置运算符.喜欢这个查询

User.find({"posts.title": "Cats are cool"},
  {username: 1, "posts.$": 1}, // add that you need to project
  (err, users) => {
    if(err) {
      // return error
    }
    return res.send(users)
})

只返回匹配的帖子

let's say there was a User model and a Post model. In this situation User's would have many posts; User would be the parent and Post would be the child. Is it possible to query for posts directly?

For instance if I wanted to do something like

app.get('/post/search/:query', (req,res) => {
       Posts.find({title: req.params.query }, (err,post) => {
            res.send(JSON.stringify(post))
       })
})

or would one have to do:

app.get('/post/search/:query',(req,res) => {

  let resultsFromQuery = [];
  User.find({'post.title':req.params.query'}, (err,user) => {
       user.posts.forEach((post) => {
           if(post.title === req.params.query){
               resultsFromQuery.push(post); 
           }
       })
  })
res.send(JSON.stringify(resultsFromQuery))

})

EDIT: Here is my schema's.

User Schema (Parent)

const mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    PostSchema = require('./post.js');

let UserSchema = new Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    posts: [PostSchema]
})

module.exports = mongoose.model('User',UserSchema);

Post Schema (Child)

const mongoose = require('mongoose'),
    Schema = mongoose.Schema;

let PostSchema = new Schema({
    title: {
        type: String
    },
    description: {
        type: String
    },
    image: {
        type: String
    },
    original_poster: {
        id: {
            type: String,
            required: true
        },
        username: {
            type: String,
            required: true
        }
    },
    tags: {
        type: [String],
        required: true
    }
})

module.exports = PostSchema;

EDIT:

Here is a sample document

the result of db.users.find({username: 'john'})

{
    "_id" : ObjectId("5a163317bf92864245250cf4"),
    "username" : "john",
    "password" : "$2a$10$mvE.UNgvBZgOURAv28xyA.UdlJi4Zj9IX.OIiOCdp/HC.Cpkuq.ru",
    "posts" : [
        {
          "_id" : ObjectId("5a17c32d54d6ef4987ea275b"),
            "title" : "Dogs are cool",
            "description" : "I like huskies",
            "image" : "https://media1.giphy.com/media/EvRj5lfd8ctUY/giphy.gif",
            "original_poster" : {
                "id" : "5a163317bf92864245250cf4",
                "username" : "john"
            },
            "tags" : [
                "puppies",
                "dogs"
            ]
        }
    ],
    "__v" : 1
}

解决方案

Yes you can find directly the post title from the user model. like bellow

User.find({"posts.title": "Cats are cool"}, (err, users) => {
  if(err) {
    // return error
  }
  return res.send(users)
})

That will return user with all post not only the matching post title. So to return only matching post title can use $ positional operator. like this query

User.find({"posts.title": "Cats are cool"},
  {username: 1, "posts.$": 1}, // add that you need to project
  (err, users) => {
    if(err) {
      // return error
    }
    return res.send(users)
})

that only return matching post

这篇关于是否可以使用猫鼬直接查询子文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆