如何将字段与MongoDB中的阵列进行比较

发布于 2025-02-11 11:49:51 字数 772 浏览 1 评论 0原文

我有以下文件。我想检索所有地址的文档。

    [  
     {
    "name": "star1",
    "active": 1,
    "address": [
      {
        "id": 1,
        "city": "newyork"
      },
      {
        "id": 2,
        "city": "sydney"
      }
    ]  
   },  
  {
    "name": "star2",
    "active": 2,
    "address": [
      {
        "id": 1,
        "city": "newyork"
      },
      {
        "id": 2,
        "city": "london"
      }
    ]  
}
]

我已经写了以下查询,它部分有效,但是它没有返回完整的文档。我不能使用Undind。我们有任何解决方案而无需使用“ Undind”。是否可以仅通过$匹配解决问题

db.collection.aggregate([
  {
    $unwind: "$address"
  },
  {
    $match: {
      $expr: {
        $eq: [
          "$active",
          "$address.id"
        ]
      },
      "address.city": "newyork"
    }
  }
])

I have a documents like below. I want to retrieve all documents whose address.city == "newyork" and address.id == active.

    [  
     {
    "name": "star1",
    "active": 1,
    "address": [
      {
        "id": 1,
        "city": "newyork"
      },
      {
        "id": 2,
        "city": "sydney"
      }
    ]  
   },  
  {
    "name": "star2",
    "active": 2,
    "address": [
      {
        "id": 1,
        "city": "newyork"
      },
      {
        "id": 2,
        "city": "london"
      }
    ]  
}
]

I have written below query and it Partially works, But It is not returning complete document. I can't use unwind. Do we have any solution without using "unwind". Is it possible to solve a problem only with $match

db.collection.aggregate([
  {
    $unwind: "$address"
  },
  {
    $match: {
      $expr: {
        $eq: [
          "$active",
          "$address.id"
        ]
      },
      "address.city": "newyork"
    }
  }
])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心激荡 2025-02-18 11:49:52

如果您需要匹配整个文档,该文档包含至少一个条目{address.id == active and adverty.city == newyork}以下是一个选项:

db.collection.aggregate([
 {
   $match: {
    $expr: {
      "$in": [
        {
          id: "$active",
          city: "newyork"
        },
        "$address"
       ]
     }
   }
 }
])

解释:

仅匹配具有至少一个在地址数组中的对象的文档== $ active and city ==“ newyork”

playground

> ,更正确的选项如下:

db.collection.aggregate([
{
 $match: {
  $expr: {
    $or: [
      {
        "$in": [
          {
            id: "$active",
            city: "newyork"
          },
          "$address"
        ]
      },
      {
        "$in": [
          {
            city: "newyork",
            id: "$active"
          },
          "$address"
        ]
      }
    ]
   }
  }
 }
])

解释:

仅匹配文档至少在数组中具有{id == $ active and active and city ==“ newyork”}或{city ==“ newyork”和id == $ active }

Playground 2

In case you need to match the whole document containing at least one entry having {address.id==active and address.city==newyork } here is an option:

db.collection.aggregate([
 {
   $match: {
    $expr: {
      "$in": [
        {
          id: "$active",
          city: "newyork"
        },
        "$address"
       ]
     }
   }
 }
])

Explained:

Match only documents having at least one object in address array with id==$active and city=="newyork"

Playground

In case we expect different order inside the address objects , the more correct option is as follow:

db.collection.aggregate([
{
 $match: {
  $expr: {
    $or: [
      {
        "$in": [
          {
            id: "$active",
            city: "newyork"
          },
          "$address"
        ]
      },
      {
        "$in": [
          {
            city: "newyork",
            id: "$active"
          },
          "$address"
        ]
      }
    ]
   }
  }
 }
])

Explained:

Match only documents having at least one object in array with { id==$active and city=="newyork" } or { city=="newyork" and id==$active }

Playground 2

似狗非友 2025-02-18 11:49:51

也许是这样的:

db.collection.aggregate([
{
"$addFields": {
  "address": {
    "$filter": {
      "input": "$address",
      "as": "a",
      "cond": {
        $and: [
          {
            $eq: [
              "$a.id",
              "$active"
            ]
          },
          {
            $eq: [
              "$a.city",
              "newyork"
            ]
          }
        ]
      }
    }
  }
}
},
{
 $match: {
  address: {
     $ne: []
    }
  }
}
])

解释:

  1. 使用AddFields/filter仅匹配数组中的匹配文档。
  2. 在未找到子图案的情况下,从数组中删除带有空地址的文档。

Playground

Maybe something like this:

db.collection.aggregate([
{
"$addFields": {
  "address": {
    "$filter": {
      "input": "$address",
      "as": "a",
      "cond": {
        $and: [
          {
            $eq: [
              "$a.id",
              "$active"
            ]
          },
          {
            $eq: [
              "$a.city",
              "newyork"
            ]
          }
        ]
      }
    }
  }
}
},
{
 $match: {
  address: {
     $ne: []
    }
  }
}
])

Explained:

  1. Use addFields/filter to match only matching documents in the array.
  2. Remove the documents with empty address from the array for the cases where no subdocuments is found.

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文