Mongodb aggregate – 排序然后获取周围的文档

huangapple go评论48阅读模式
英文:

Mongodb aggregate - Sort then get surrounding documents

问题

I'm providing the translation for the code sections you've mentioned:

我正在尝试编写一个MongoDB聚合查询以应用两级排序然后获取已排序集合中特定文档之前和之后的两个文档首先我尝试构建一个查询以获取之后文档

文档是无序插入的

```javascript
db.test.insertMany([
   { name: 'V', type: 'Trap' },
   { name: 'J', type: 'Magic' },
   { name: 'B', type: 'Effect' }
])

要在每个type内按字母顺序排序,可以执行以下操作:

db.test.aggregate([{ "$sort": { type: 1, name: 1 } }])

结果:
{ name: 'B', type: 'Effect' }
{ name: 'J', type: 'Magic' }
{ name: 'V', type: 'Trap' }

我正在尝试使用以下查询(带有替代)来获取“之后”的文档:

[
  { $sort: { type: 1, name: 1 } },
  {
    $match: {
      name: {
        $gt: <name>,
      },
      type: {
        $gte: <type>,
      },
    },
  },
  { $limit: 1 }
]

例如:

文档{ name: 'K', type: 'Trap' }应该位于J和V之间。

  • 上述查询正确返回“V”。

文档{ name: 'C', type: 'Effect' }应该位于B和J之间。

  • 上述查询正确返回“J”。

然而,文档{ name: 'K', type: 'Effect' }也应该位于B和J之间,因为它应该保留在“Effect”分组中。

  • 该查询错误地返回了“V”(应该是J)。

删除$match属性中的任何一个会导致其他情况下的错误结果。似乎无法使用$and /或来在所有情况下获得正确的结果。

对于相反的情况,我的“之前”查询如下(在某些情况下不起作用):

{ $sort: { type: -1, name: -1 } },
{
   $match: {
      name: { $lt: card.name },
      type: { $lte: card.type }
   }
},
{ $limit: 1 }

Please let me know if you need any further assistance or specific translations.

<details>
<summary>英文:</summary>

I&#39;m trying to write a mongodb aggregate to apply a 2-level sort and then get the 2 documents before and after a particular document in the sorted set. To start, I&#39;m trying to build a query for the &quot;after&quot; document

Documents are inserted out of order:

db.test.insertMany([
{ name: 'V', type: 'Trap' },
{ name: 'J', type: 'Magic' },
{ name: 'B', type: 'Effect' }
])


To sort alphabetically within each `type` I can do:

db.test.aggregate([{ "$sort": { type: 1, name: 1 } }])

Result:
{ name: 'B', type: 'Effect' }
{ name: 'J', type: 'Magic' }
{ name: 'V', type: 'Trap' }


I&#39;m trying to use the following query (with &lt;param&gt; replacements) to get the &quot;after&quot; document:

[
{ $sort: { type: 1, name: 1 } },
{
$match: {
name: {
$gt: <name>,
},
type: {
$gte: <type>,
},
},
},
{ $limit: 1 }
]


For example:

Document ```{ name: &#39;K&#39;, type: &#39;Trap&#39; }``` should go between J &amp; V.

 - The above query correctly gives &quot;V&quot;.

Document ```{ name: &#39;C&#39;, type: &#39;Effect&#39; }``` should go between B &amp; J.

- The above query correctly gives &quot;J&quot;.
 

However, document```{ name: &#39;K&#39;, type: &#39;Effect&#39; }``` also needs to go between  B &amp; J since it should remain in the &quot;Effect&quot; grouping.

- The query incorrectly returns &quot;V&quot; again (should be J).

Removing either of the $match properties gives incorrect results in other cases. Can&#39;t seem to use $and/or to get correct results in all cases either


For the reverse, my &quot;before&quot; query is as following (not working in all cases):

{ $sort: { type: -1, name: -1 } },
{
$match: {
name: { $lt: card.name },
type: { $lte: card.type }
}
},
{ $limit: 1 }



</details>


# 答案1
**得分**: 1

你可以编写一个匹配查询,检查一个“或”条件,其中检查“type”大于给定的类型,或者如果类型等于给定的类型,然后检查“name”是否大于给定的名称。要获取之前的文档,请将“gt”替换为“lt”。

```javascript
db.collection.aggregate([
  { $sort: { type: 1, name: 1 } },
  {
    $match: {
      $or: [
        { type: { $gt: <type> } },
        { $and: [{ type: <type> }, { name: { $gt: <name> } }] }
      ]
    }
  },
  { $limit: 1 }
])

playground

英文:

can write a match query which checks an or condition where check type is greater than the given type or if the type is equal to the given type then check if the name is greater than the given name. To get the before document replace gt with lt

db.collection.aggregate([
  { $sort: { type: 1, name: 1 } },
  {
    $match: {
      $or: [
        { type: { $gt: &lt;type&gt; } },
        { $and: [{ type: &lt;type&gt; }, { name: { $gt: &lt;name&gt; } }] }
      ]
    }
  },
  { $limit: 1 }
])

playground

huangapple
  • 本文由 发表于 2023年4月19日 16:28:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052294.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定