如何使用带有索引的 CouchDB Mango 查询 (/db/_find) 来选择多个 _id 键

问题描述 投票:0回答:1

我正在使用 CouchDB 3.1.1 对包含大量文档的数据库执行 Mango 查询。我的应用程序中一个非常常见的要求是对一组非常具体且动态的文档执行查询。据我目前的了解,这些是我如何面对问题的唯一选择:

  1. 向 /db/_find 发出多个请求,每个请求都具有不同的“_id”
  2. 对 /db/_find 进行一次调用

我可以实现第二个选择的方法:

  • 对所有“_id”使用“$or”数组:值对
  • 对“_id”键的所有值使用“$or”数组

第二个选择是我更喜欢使用的,因为发出多个 POST 请求会产生开销。不幸的是,使用“$or”似乎会妨碍查询引擎使用“_id”索引。

因此,选择 #1 每笔交易以 2 毫秒的速度返回,但结果未排序(需要我的应用程序进行排序)。选择 #2,给定 2 个 _ids 的数组,无论 $or 语法如何,渲染都需要超过 3 秒。

针对特定文档集使用 CouchDB Mango 查询索引的最有效方法是什么?

快速示例:使用单个 _id 的结果

{
   "selector": {
      "_id": "184094"
   },
   "fields": [
      "_id"
   ]
}

检查的文件:26,312
返回结果:1
执行时间:2毫秒

慢速示例:使用 $or 键/值对的结果

{
   "selector": {
      "$or": [
         {
            "_id": "184094"
         },
         {
            "_id": "157533"
         }
      ]
   },
   "fields": [
      "_id"
   ]
}

检查的文件:26,312
返回结果:2
执行时间:2,454 ms

慢示例:使用 $ 或值数组的结果

{
   "selector": {
      "_id": {
         "$or": [
            "184094",
            "157533"
         ]
      }
   },
   "fields": [
      "_id"
   ]
}

检查的文件:26,312
返回结果:2
执行时间:2,522 ms

慢示例:使用 $in 的结果(这是非法的,但仍然返回结果)

{
   "selector": {
      "_id": {
         "$in": [
            "184094",
            "157533"
         ]
      }
   },
   "fields": [
      "_id"
   ]
}

检查的文件:26,312
返回结果:2
执行时间:2,618 ms

Index:_id

的注册索引
{
  "_id": "_design/508b5b51e6085c2f96444b82aced1e5dfec986b2",
  "_rev": "1-f951eb482f9a521752adfdb6718a6a59",
  "language": "query",
  "views": {
    "foo-index": {
      "map": {
        "fields": {
          "_id": "asc"
        },
        "partial_filter_selector": {}
      },
      "reduce": "_count",
      "options": {
        "def": {
          "fields": [
            "_id"
          ]
}}}}}

Explain:对其中一个慢速查询进行“解释”摘要。请注意,使用了注册索引。

{
 "dbname": "dnp_person_comment",
 "index": {
  "ddoc": "_design/508b5b51e6085c2f96444b82aced1e5dfec986b2",
  "name": "foo-index",
  "type": "json",
  "partitioned": false,
  "def": {
   "fields": [
    {
     "_id": "asc"
    }
   ]
  }
 },
 "partitioned": false,
 "selector": {
  "$or": [
   {
    "_id": {
     "$eq": "184094"
    }
   },
   {
    "_id": {
     "$eq": "157533"
    }
   }
  ]
 },
 "opts": {
  "use_index": [],
  "bookmark": "nil",
  "limit": 25,
  "skip": 0,
  "sort": {},
  "fields": [
   "_id"
  ],
  "partition": "",
  "r": [
   49
  ],
  "conflicts": false,
  "stale": false,
  "update": true,
  "stable": false,
  "execution_stats": false
 },
 "limit": 25,
 "skip": 0,
 "fields": [
  "_id"
 ],
 "mrargs": {
  "include_docs": true,
  "view_type": "map",
  "reduce": false,
  "partition": null,
  "start_key": [],
  "end_key": [
   "<MAX>"
  ],
  "direction": "fwd",
  "stable": false,
  "update": true,
  "conflicts": "undefined"
 }
}
couchdb couchdb-mango
1个回答
-1
投票

这应该有助于理解为什么以及何时

$or
可能会很慢。 https://github.com/apache/couchdb/issues/1852

我仍然想知道是否有任何好的方法可以通过选择器中指定的 ID 来获取文档。

© www.soinside.com 2019 - 2024. All rights reserved.