GVKun编程网logo

我们如何使用 mongodb 和 nodejs 在 $look up 聚合管道中找到 $near(mongodb聚合管道操作符)

14

本文将带您了解关于我们如何使用mongodb和nodejs在$lookup聚合管道中找到$near的新内容,同时我们还将为您解释mongodb聚合管道操作符的相关知识,另外,我们还将为您提供关于jav

本文将带您了解关于我们如何使用 mongodb 和 nodejs 在 $look up 聚合管道中找到 $near的新内容,同时我们还将为您解释mongodb聚合管道操作符的相关知识,另外,我们还将为您提供关于java-为什么Spring Data MongoDB在聚合管道中拒绝包含$的字段名?、MongoDB 聚合管道 & 关联处理、MongoDB 聚合管道&关联处理、MongoDB 聚合管道使用的实用信息。

本文目录一览:

我们如何使用 mongodb 和 nodejs 在 $look up 聚合管道中找到 $near(mongodb聚合管道操作符)

我们如何使用 mongodb 和 nodejs 在 $look up 聚合管道中找到 $near(mongodb聚合管道操作符)

我有两个集合,一个是产品,我在其中存储价格,图像和位置,另一个集合,我将产品集合的 _id 存储为 product_id 和产品的其他详细信息。现在我想查找产品,它是基于两个集合的位置的详细信息。我无法发布我的整个代码。

java-为什么Spring Data MongoDB在聚合管道中拒绝包含$的字段名?

java-为什么Spring Data MongoDB在聚合管道中拒绝包含$的字段名?

使用Spring Data的Projectionoperation类在MongoDB上创建聚合查询时,使用带有“ $”(例如’test $’)字符的字段会导致IllegalArgumentException

验证spring数据mongodb源时,我注意到在AggregationField类的构造函数中,对字段名称进行了清理. Fields.java Class

private static String cleanUp(String source) {

    if (Aggregation.SystemVariable.isReferingToSystemVariable(source)) {
        return source;
    }

    int dollarIndex = source.lastIndexOf('$');
    return dollarIndex == -1 ? source : source.substring(dollarIndex + 1);
}

MongoDB中字段的命名法不鼓励使用“ $”字符,否则这是Spring Data问题吗?

最佳答案
MongoDB官方驱动程序当前不支持的reference documentation clearly states:

IMPORTANT

The MongoDB Query Language cannot always meaningfully express queries over documents whose field names contain these characters (see SERVER-30575). Until support is added in the query language,the use of $and . in field names is not recommended and is not supported by the official MongoDB drivers.
{quote}

即Spring Data无法支持该功能,除非对此提供支持,以使其成为正式的Java驱动程序.

MongoDB 聚合管道 & 关联处理

MongoDB 聚合管道 & 关联处理

关联查询

汇率表数据

db.forex.insert([
    {
        ccy: "USD",
        rate: 6.91,
        date: new Date("2018-12-21")
    },
    {
        ccy: "GBP",
        rate: 8.72,
        date: new Date("2018-08-21")
    },
    {
        ccy: "CNY",
        rate: 1.0,
        date: new Date("2018-10-21")
    }
])

用户表数据

> db.accounts.find().pretty()
{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP"
}

使用 lookup 来对表进行关联查询

  • from 要关联的表
  • localField 当前表字段
  • foreignField 当前表字段要关联的外表字段
  • as 新增字段展示关联的结果
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            localField: ''currency'',
            foreignField: "ccy",
            as: "forexData"
        }
    }
])

得出如下结果

{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ],
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199942"),
   "ccy" : "USD",
   "rate" : 6.91,
   "date" : ISODate("2018-12-21T00:00:00Z")
  },
  {
   "_id" : ObjectId("5d82226fc404a31cf5199944"),
   "ccy" : "CNY",
   "rate" : 1,
   "date" : ISODate("2018-10-21T00:00:00Z")
  }
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP",
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}

关联修改

将特定日期的外汇汇率写入银行账户文档

# 所有账号的 forexData 匹配的都是 2018-08-21 的记录
# 使用了 pipeline 之后,就不能同时使用 localField 与 foreignField 了
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            pipeline: [
                {
                    $match: {
                        date: new Date("2018-08-21")
                    }
                }
            ],
            as: "forexData"
        }
    }
])
{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ],
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP",
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}

将特定日期的外汇汇率写入余额大于 100 的银行账户文档

# 使用let来区分pipeline用到的字段为本表字段还是外表字段
# 要使用let声明的变量时,需要在pipeline中使用 $expr
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            let: {
                bal: "$balance"
            },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                {
                                    $eq: ["$date", new Date("2018-08-21")]
                                },
                                {
                                    $gt: ["$$bal", 100]
                                }
                            ]
                        }
                    }
                }
            ],
            as: "forexData"
        }
    }
])

MongoDB 聚合管道&关联处理

MongoDB 聚合管道&关联处理

关联查询

汇率表数据

db.forex.insert([
    {
        ccy: "USD",
        rate: 6.91,
        date: new Date("2018-12-21")
    },
    {
        ccy: "GBP",
        rate: 8.72,
        date: new Date("2018-08-21")
    },
    {
        ccy: "CNY",
        rate: 1.0,
        date: new Date("2018-10-21")
    }
])

用户表数据

> db.accounts.find().pretty()
{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP"
}

使用lookup来对表进行关联查询

  • from 要关联的表
  • localField 当前表字段
  • foreignField 当前表字段要关联的外表字段
  • as 新增字段展示关联的结果
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            localField: ''currency'',
            foreignField: "ccy",
            as: "forexData"
        }
    }
])

得出如下结果

{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ],
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199942"),
   "ccy" : "USD",
   "rate" : 6.91,
   "date" : ISODate("2018-12-21T00:00:00Z")
  },
  {
   "_id" : ObjectId("5d82226fc404a31cf5199944"),
   "ccy" : "CNY",
   "rate" : 1,
   "date" : ISODate("2018-10-21T00:00:00Z")
  }
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP",
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}

关联修改

将特定日期的外汇汇率写入银行账户文档

# 所有账号的 forexData 匹配的都是 2018-08-21 的记录
# 使用了 pipeline 之后,就不能同时使用 localField 与 foreignField 了
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            pipeline: [
                {
                    $match: {
                        date: new Date("2018-08-21")
                    }
                }
            ],
            as: "forexData"
        }
    }
])
{
 "_id" : ObjectId("5d80c37349f3060f1212a055"),
 "name" : {
  "first_name" : "qingquan",
  "last_name" : "zeng"
 },
 "balance" : 100,
 "currency" : [
  "CNY",
  "USD"
 ],
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}
{
 "_id" : ObjectId("5d80c37349f3060f1212a056"),
 "name" : {
  "first_name" : "fengxia",
  "last_name" : "yu"
 },
 "balance" : 200,
 "currency" : "GBP",
 "forexData" : [
  {
   "_id" : ObjectId("5d82226fc404a31cf5199943"),
   "ccy" : "GBP",
   "rate" : 8.72,
   "date" : ISODate("2018-08-21T00:00:00Z")
  }
 ]
}

将特定日期的外汇汇率写入余额大于100的银行账户文档

# 使用let来区分pipeline用到的字段为本表字段还是外表字段
# 要使用let声明的变量时,需要在pipeline中使用 $expr
db.accounts.aggregate([
    {
        $lookup: {
            from: "forex",
            let: {
                bal: "$balance"
            },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                {
                                    $eq: ["$date", new Date("2018-08-21")]
                                },
                                {
                                    $gt: ["$$bal", 100]
                                }
                            ]
                        }
                    }
                }
            ],
            as: "forexData"
        }
    }
])

MongoDB 聚合管道使用

MongoDB 聚合管道使用

数据准备

[
    {
        "name": {
            "first_name": "qingquan",
            "last_name": "zeng"
        },
        "balance": 100
    },
    {
        "name": {
            "first_name": "fengxia",
            "last_name": "yu"
        },
        "balance": 200
    }
]

插入数据

db.accounts.insert([{"name": {"first_name": "qingquan","last_name": "zeng"},"balance": 100},{"name": {"first_name": "fengxia","last_name": "yu"},"balance": 200}])

数据查询

$project

# aggregate 中的 $project 除了可以实现投影效果,还直接使用了一个不存在的字段 client_name ,相当于 mysql 中的 as 语法
> db.accounts.aggregate([{
... $project:{
... _id:0,
... balance:1,
... client_name:"$name.first_name"
... }
... }]);
{ "balance" : 100, "client_name" : "qingquan" }
{ "balance" : 200, "client_name" : "fengxia" }
# 由于 middle_name 不存在,产生的结果就为 null 了
> db.accounts.aggregate([{
... $project:{
... _id:0,
... balance:1,
... name_arr:["$name.first_name","$name.middle_name","$name.first_name"]
... }
... }]);
{ "balance" : 100, "name_arr" : [ "qingquan", null, "qingquan" ] }
{ "balance" : 200, "name_arr" : [ "fengxia", null, "fengxia" ] }

$match 中使用的文档筛选语法,和读取文档时的筛选语法相同

db.accounts.aggregate([
    {
        $match: {
            "name.first_name": ''fengxia''
        }
    }
])
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200 }

$project$match$skip$limit 相结合

db.accounts.aggregate([
    {
        $match: {
            $or: [
                {
                    "name.first_name": ''fengxia''
                },
                {
                    "name.first_name": ''qingquan''
                },          
            ]
        }
    },
    {
        $project: {
            _id: 0
        }
    },
    {
        $skip: 1
    },
    {
        $limit: 1
    }
])
{ "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200 }

$unwind 对本节的数据进行修改

db.accounts.update({''name.first_name'':''qingquan''},{
 $set:{
  "currency":["CNY","USD"]
 }
})

db.accounts.update({''name.first_name'':''fengxia''},{
 $set:{
  "currency":"GBP"
 }
})

修改后的数据如下,一个用户的 currency 是数组,另一个用户的 currency 是字符串

> db.accounts.find()
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : [ "CNY", "USD" ] }
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }

使用 unwind 对数组元素进行平铺,可以将 currency 为数组的记录,从一条记录拆分为多条记录

db.accounts.aggregate([
    {
        $unwind: {
            path: "$currency"
        }
    }
])
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "CNY" }
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de8"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "USD" }
{ "_id" : ObjectId("5d80fd4471c6b2236fb80de9"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }

为了方便排查,还可以在设定一个字段,用于数组展开后标记每个元素在原数组的位置

db.accounts.aggregate([
    {
        $unwind: {
            path: "$currency",
            includeArrayIndex:"origin_index"
        }
    }
])
{ "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "CNY", "origin_index" : NumberLong(0) }
{ "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : "USD", "origin_index" : NumberLong(1) }
{ "_id" : ObjectId("5d80c37349f3060f1212a056"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP", "origin_index" : null }

还有一点需要注意的是,$unwind 在产生结果前,默认会直接过滤掉如下记录:

  • currency 字段为空数组
  • currency 字段不存在
  • currency 字段为 null

如果不想过滤的话,可以设定 preserveNullAndEmptyArrays 为 true

db.accounts.aggregate([
    {
        $unwind: {
            path: "$currency",
            includeArrayIndex: "origin_index",
            preserveNullAndEmptyArrays: true
        }
    }
])

$sort

  • 1 从小到大
  • -1 从大到小
db.accounts.aggregate([
    {
        $sort: {
            balance: -1
        }
    }
])
{ "_id" : ObjectId("5d80c37349f3060f1212a056"), "name" : { "first_name" : "fengxia", "last_name" : "yu" }, "balance" : 200, "currency" : "GBP" }
{ "_id" : ObjectId("5d80c37349f3060f1212a055"), "name" : { "first_name" : "qingquan", "last_name" : "zeng" }, "balance" : 100, "currency" : [ "CNY", "USD" ] }

MongoDB 聚合操作重复问题 https://jacoobwang.github.io/2018/01/08/MongoDb%E8%81%9A%E5%90%88%E6%93%8D%E4%BD%9C%E9%87%8D%E5%A4%8D%E9%97%AE%E9%A2%98/

今天关于我们如何使用 mongodb 和 nodejs 在 $look up 聚合管道中找到 $nearmongodb聚合管道操作符的介绍到此结束,谢谢您的阅读,有关java-为什么Spring Data MongoDB在聚合管道中拒绝包含$的字段名?、MongoDB 聚合管道 & 关联处理、MongoDB 聚合管道&关联处理、MongoDB 聚合管道使用等更多相关知识的信息可以在本站进行查询。

本文标签: