在mongodb中的$ lookup中应用条件

时间:2018-09-28 07:23:15

标签: mongodb aggregation-framework

我是mongoDb的新手。我设置了两个收藏。 1)书2)评论

#![feature(fn_traits)]
#![feature(unboxed_closures)]

use std::ops::*;

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Scalar {
    I64(i64),
    I32(i32),
    //many many others
}

pub trait TMath: Add + Mul + Sized {} //mark numerical types

impl<T: Add + Mul> TMath for T {}

struct Adder;

impl FnOnce<(i64, i64)> for Adder {
    type Output = i64;
    extern "rust-call" fn call_once(self, args: (i64, i64)) -> i64 {
        args.0 + args.1
    }
}

impl FnMut<(i64, i64)> for Adder {
    extern "rust-call" fn call_mut(&mut self, args: (i64, i64)) -> i64 {
        args.0 + args.1
    }
}

impl Fn<(i64, i64)> for Adder {
    extern "rust-call" fn call(&self, args: (i64, i64)) -> i64 {
        args.0 + args.1
    }
}

impl FnOnce<(i32, i32)> for Adder {
    type Output = i32;
    extern "rust-call" fn call_once(self, args: (i32, i32)) -> i32 {
        args.0 + args.1
    }
}

impl FnMut<(i32, i32)> for Adder {
    extern "rust-call" fn call_mut(&mut self, args: (i32, i32)) -> i32 {
        args.0 + args.1
    }
}

impl Fn<(i32, i32)> for Adder {
    extern "rust-call" fn call(&self, args: (i32, i32)) -> i32  {
        args.0 + args.1
    }
}

fn bin_op<F>(apply: &F, x: Scalar, y: Scalar) -> Scalar
    where
        F: Fn(i64, i64) -> i64,
        F: Fn(i32, i32) -> i32,
{
    match (x, y) {
        (Scalar::I64(a), Scalar::I64(b))
            => Scalar::I64((apply as &Fn(i64, i64) -> i64)(a, b)),
        (Scalar::I32(a), Scalar::I32(b))
            => Scalar::I32((apply as &Fn(i32, i32) -> i32)(a, b)),
        _ => unreachable!(),
    }
}

fn main() {
    let result = bin_op(&Adder, Scalar::I32(1), Scalar::I32(2));
    println!("{:?}", result);
}

评论为:

book : 
_id
title
author
posted
price

我想得到那些带有_id bookId comment status 的书的评论。

我已经尝试过了。

status = 1

当我调用我的API时,我是在邮递员那里得到的。

return new promise((resolve, reject) => {
    db.collection('book').aggregate([
        {
            $lookup:{
                from:'comments',
                localField: "_id",
                foreignField: "bookId",
                as: "comments"                                                                  
            }
        }      
    ]).toArray().then((result) => {
        if(result.length > 0){
            res.send({ status: 1, message: "Success.", data:result });
        }else{
            res.send({ status: 0, message: "No data found." });
        }
    }).catch((err) => {
        res.send({ status: 0, message: "Something went wrong."});
    });
});

我需要注释状态为1的数据。我尝试在{ "status": 1, "message": "Success.", "data": [ { "_id": "5bacad201bff841afb40791f", "title": "Game of thrones", "author": "John snow", "posted": "16/07/1995", "price": 1000, "comments": [ { "_id": "5bacc31aa2d365256cab31ce", "bookId": "5bacad201bff841afb40791f", "comment": "Winter is comming" }, { "_id": "5bacc3f65c716925df953615", "bookId": "5bacad201bff841afb40791f", "comment": "It has a level of politics" }, { "_id": "5bacd60ea38cc526f1fee1d1", "bookId": "5bacad201bff841afb40791f", "comment": "It has a level of politics", "status": 1 } ] }, { "_id": "5bacad601bff841afb407920", "title": "Breaking bed", "author": "Haison burg", "posted": "20/08/2002", "price": 550, "comments": [] } ] } 之后使用$match,但是它不起作用。我也尝试过使用$lookup,这对我也不起作用。由于刚开始学习mongodb,可能以错误的方式设置了它。

2 个答案:

答案 0 :(得分:2)

您可以在此处使用$addFields$filter聚合

db.collection("book").aggregate([
  { "$lookup": {
    "from": "comments",
    "localField": "_id",
    "foreignField": "bookId",
    "as": "comments"                                                                  
  }},
  { "$addFields": {
    "comments": {
      "$filter": {
        "input": "$comments",
        "cond": { "$eq": ["$$this.status", 1] }
      }
    }
  }}
])

答案 1 :(得分:0)

MongoDB v3.6.3开始,将实现以下最快的查询性能:

确保在bookId集合的statuscomments字段上有一个索引:

db.comments.createIndex({ "bookId": 1, "status": 1 })

然后使用pipeline阶段(documentation)的新$lookup属性:

db.books.aggregate([{
    "$lookup": {
        "from": "comments",
        "let": { "bId": "$_id" },
        "pipeline": [{
            "$match": {
                $expr: { $eq: [ "$bookId", "$$bId" ] },
                "status": 1
            }
        }],
        "as": "comments"
    }
}])