从PouchDB(或CouchDB)获取随机文档

时间:2021-06-24 22:50:48

I'm designing a quiz app with Angular and Ionic. I have about 2000 questions in json format and I choose PouchDB as database. CouchDB is perfect for me: I can add new question on a server and app auto update question and answer.

我正在设计一个带有角和离子的测试应用。我有大约2000个json格式的问题,我选择PouchDB作为数据库。CouchDB非常适合我:我可以在服务器和应用程序自动更新问题和答案上添加新问题。

But I have a doubt now: I cannot find a way to get random docs from Pouch. With my app I will generate quizzes from some selected section and I must get a variable number of docs from my DB.

但我现在有一个疑问:我找不到一个方法从口袋里找到随机的医生。通过我的应用,我将从一些选定的部分产生测验,我必须从我的DB中获得可变数量的文档。

I'm using the db.allDocs([options], [callback]) api, I can set a limit but I cannot find a way to get random doc.

我用db。allDocs(【选项】,【回调】)api,我可以设置一个限制,但是我找不到随机获取doc的方法。

Is there any solution?

有什么解决方案吗?

2 个解决方案

#1


1  

The first solution given by @nlawson isn't always working, for example I had to delete every document fetched so I lose the sequence of IDs, for example:

@nlawson给出的第一个解决方案并不总是有效,例如,我必须删除所有获取的文档,这样我就丢失了id序列,例如:

I had a list of documents with ids from 1 to 5

我有一个id从1到5的文件列表

1- random is 3

1 -随机是3

2- get document with id 3

2-获取id为3的文档

3- delete document with id 3 State of the database [1,2,4,5]

3-删除数据库id为3状态的文档[1,2,4,5]

4- if random is anything but 3 repeat steps above, but if random is 3 or any id already deleted it cause problems, so this solution wasn't working, so I found another solution which is:

4-如果random不是上面的3个重复步骤,但如果random是3,或者任何id已经被删除,就会导致问题,所以这个解决方案行不通,所以我找到了另一个解决方案:

ANSWER:

答:

Using the Mango querie find(), with this code

使用Mango querie find()和此代码

let rand = Math.floor(Math.random() * (max - min + 1)) + min;

db.find({
   selector: {_id: {$gte : '1'}},
   limit : 1,
   skip : rand-1,
});

First of all I get a random number, the max is the number of documents in my database and the min is 1 as the first id given to the first document.

首先我得到一个随机数,最大值是我的数据库中的文档数最小值是1作为第一个文档的id。

After that I execute the find() query to select documents with an id great or equal to 1 (basically all), limit the query to retrieve only the first and start retrieving from rand-1.

之后,我执行find()查询以选择id为great或等于1(基本上都是)的文档,将查询限制为只检索第一个文档,并从r -1开始检索。

To reuse our first example with rand equal 3 it will be something like that:

为了重复使用第一个rand = 3的例子它会是这样的:

1- get all documents with an ID great or equal 1 => [1,2,3,4,5]

1-获取ID为great或等于1的所有文档=> [1,2,3,4,5]

2- starting from rand-1 witch is 3-1=2 get the a limited number of documents the limit is 1 => [2]

2-从rand-1女巫开始,3-1=2得到有限数量的文档,限制为1 [2]

So it will always return the document on the position rand.

所以它总是返回在兰德位置上的文档。

P.S: to use find() you must install on top of pouch this library pouchdb.find.js

P。S:要使用find(),您必须将这个库中的pouchdb.find.js安装在育儿袋的顶部

#2


0  

You could

你可以

  1. Give your docs an _id of '1', '2', '3', etc., then use Math.random() to get() one randomly.

    给你的文档一个_id为“1”、“2”、“3”等等,然后使用Math.random()随机获取()一个。

  2. Or you could read in all the IDs using bulkDocs and then pick one randomly to get(), but that might be bad for performance if you have a lot of docs:

    或者你可以使用bulkDocs读取所有的id,然后随机选择一个获取(),但是如果你有很多这样的文档,可能会影响性能:

db.allDocs().then(function (res) {
  var ids = res.rows.map(function (row) { return row.id; });
  var index = Math.floor(Math.random() * ids.length);
  return db.get(ids[index]);
}).then(function (randomDoc) {
  // you got a randomDoc
}).catch(console.log.bind(console))

#1


1  

The first solution given by @nlawson isn't always working, for example I had to delete every document fetched so I lose the sequence of IDs, for example:

@nlawson给出的第一个解决方案并不总是有效,例如,我必须删除所有获取的文档,这样我就丢失了id序列,例如:

I had a list of documents with ids from 1 to 5

我有一个id从1到5的文件列表

1- random is 3

1 -随机是3

2- get document with id 3

2-获取id为3的文档

3- delete document with id 3 State of the database [1,2,4,5]

3-删除数据库id为3状态的文档[1,2,4,5]

4- if random is anything but 3 repeat steps above, but if random is 3 or any id already deleted it cause problems, so this solution wasn't working, so I found another solution which is:

4-如果random不是上面的3个重复步骤,但如果random是3,或者任何id已经被删除,就会导致问题,所以这个解决方案行不通,所以我找到了另一个解决方案:

ANSWER:

答:

Using the Mango querie find(), with this code

使用Mango querie find()和此代码

let rand = Math.floor(Math.random() * (max - min + 1)) + min;

db.find({
   selector: {_id: {$gte : '1'}},
   limit : 1,
   skip : rand-1,
});

First of all I get a random number, the max is the number of documents in my database and the min is 1 as the first id given to the first document.

首先我得到一个随机数,最大值是我的数据库中的文档数最小值是1作为第一个文档的id。

After that I execute the find() query to select documents with an id great or equal to 1 (basically all), limit the query to retrieve only the first and start retrieving from rand-1.

之后,我执行find()查询以选择id为great或等于1(基本上都是)的文档,将查询限制为只检索第一个文档,并从r -1开始检索。

To reuse our first example with rand equal 3 it will be something like that:

为了重复使用第一个rand = 3的例子它会是这样的:

1- get all documents with an ID great or equal 1 => [1,2,3,4,5]

1-获取ID为great或等于1的所有文档=> [1,2,3,4,5]

2- starting from rand-1 witch is 3-1=2 get the a limited number of documents the limit is 1 => [2]

2-从rand-1女巫开始,3-1=2得到有限数量的文档,限制为1 [2]

So it will always return the document on the position rand.

所以它总是返回在兰德位置上的文档。

P.S: to use find() you must install on top of pouch this library pouchdb.find.js

P。S:要使用find(),您必须将这个库中的pouchdb.find.js安装在育儿袋的顶部

#2


0  

You could

你可以

  1. Give your docs an _id of '1', '2', '3', etc., then use Math.random() to get() one randomly.

    给你的文档一个_id为“1”、“2”、“3”等等,然后使用Math.random()随机获取()一个。

  2. Or you could read in all the IDs using bulkDocs and then pick one randomly to get(), but that might be bad for performance if you have a lot of docs:

    或者你可以使用bulkDocs读取所有的id,然后随机选择一个获取(),但是如果你有很多这样的文档,可能会影响性能:

db.allDocs().then(function (res) {
  var ids = res.rows.map(function (row) { return row.id; });
  var index = Math.floor(Math.random() * ids.length);
  return db.get(ids[index]);
}).then(function (randomDoc) {
  // you got a randomDoc
}).catch(console.log.bind(console))