【问题标题】:How to get multiple docs using single query pouchDB如何使用单个查询 pouchDB 获取多个文档
【发布时间】:2020-07-07 21:19:01
【问题描述】:

我是 pocuhDB 的新手, 我想在单个查询中获取多个文档。

这是我的文档结构:考虑以下 4 个文档

{
"type": "SHIP",
"regNumber": "11"
},

{
"type": "SHIP",
"regNumber": "29"
},

{
"type": "SHIP",
"regNumber": "22"
},

{
"type": "SHIP",
"regNumber": "67"
}

我想获取与我在其他数组中的 regNumber 匹配的所有文档: myArray = ["11","22","67"]

预期输出:

    {
    "type": "SHIP",
    "regNumber": "11"
    },

    {
    "type": "SHIP",
    "regNumber": "22"
    },

    {
    "type": "SHIP",
    "regNumber": "67"
    }

提前致谢!

【问题讨论】:

    标签: pouchdb


    【解决方案1】:

    这很容易使用 pouchDB Mango 查询来实现,特别是使用 $in 运算符。

    假设希望同时查询type 和任意数量的regNumber 项目,则该策略是直截了当的。首先创建一个索引,比如在sn -p:

      // create the index
      await db.createIndex({
        index: {
          fields: ['type', 'regNumber'],
          ddoc: "type-regNumber-index"
        }
      });
    

    其中fields 定义要索引的文档字段; ddoc 为索引命名。

    之后构造查询就很简单了;再次到sn-p,

      const query = {
        "selector": {
          "$and": [{
              "type": type
            },
            {
              "regNumber": {
                "$in": regNumbers
              }
            }
          ]
        },
        "use_index": "type-regNumber-index"
      }
    

    其中regNumbers 是一个值数组,type 是一个字符串值。

    运行并阅读代码 sn-p,我已尝试将其保持在最低限度。

    // find button click handler
    const regNumberQuery = async(type, regNumbers, viewResult) => {
      const query = {
        "selector": {
          "$and": [{
              "type": type
            },
            {
              "regNumber": {
                "$in": regNumbers
              }
            }
          ]
        },
        "use_index": "type-regNumber-index"
      }
    
      // query
      const result = await db.find(query);
    
      // display results   
      if (result.docs.length) {
        // clean up prior result
        viewResult.innerHTML = '';
        result.docs.forEach(doc => {
          // display doc as a row 
          const pre = creEl('pre');
          pre.innerText = ['type:', type, '\nregNumber:', doc.regNumber].join(' ');
          pre.classList.add('border-bottom');
          viewResult.appendChild(pre);
    
        });
      } else {
        // no results
        viewResult.innerHTML = '<div>No results.</div>';
      }
      // display the query i.e. selector.
      const pre = creEl('pre');
      pre.innerText = JSON.stringify(query, null, 3);
      viewResult.appendChild(pre);
    
    }
    
    //
    //  boilerplate code
    //
    
    // canned test documents
    const getDocsToInstall = () => {
      return [{
          "type": "SHIP",
          "regNumber": "11"
        },
        {
          "type": "SHIP",
          "regNumber": "29"
        },
        {
          "type": "SHIP",
          "regNumber": "22"
        },
        {
          "type": "SHIP",
          "regNumber": "67"
        }
      ]
    }
    // init db instance
    let db;
    
    const initDb = async() => {
    
      // create an in-memory db
      db = new PouchDB('test', {
        adapter: 'memory'
      });
    
      // add test docs
      await db.bulkDocs(getDocsToInstall());
    
      // create the type/regNumber index
      await db.createIndex({
        index: {
          fields: ['type', 'regNumber'],
          ddoc: "type-regNumber-index"
        }
      });
    }
    
    // initialize the db then show search controls.
    initDb().then(() => {
      getEl(g_view_result).classList.remove('hide')
    });
    
    
    // conveniences
    const getEl = id => document.getElementById(id);
    const creEl = id => document.createElement(id);
    .hide {
      display: none
    }
    
    .label {
      text-align: right;
      margin-right: 1em;
    }
    
    .hints {
      margin-left: 1em;
      font-size: smaller;
    }
    
    .border-top {
      border-top: 1px solid;
    }
    
    .border-bottom {
      border-bottom: 1px solid;
      padding: 1em 1em;
    }
    <script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.find.min.js"></script>
    <script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
    
    <table id='view' class=''>
      <tr>
        <td>
          <input id='regNumbersCSV' type='text' value='11,29,22,67' />
          <label class='hints' for='regNumbersCSV'>regNumbers (e.g. 11,29,22,67)</label>
          <div>
            <input id='type' type='text' value='SHIP' />
            <label class='hints' for='type'>Type (e.g. SHIP)</label>
            <div style='margin-top:1em'>
              <button onclick="regNumberQuery(
              getEl('type').value.trim(),
              getEl('regNumbersCSV').value.split(',').map(n => n.trim()),
              getEl('viewResult'))">Find</button>
        </td>
      </tr>
    </table>
    <div style='margin-top:2em'></div>
    <div id='viewResult' class='border-top'>
    </div>

    【讨论】:

      【解决方案2】:

      如果您使用的是 couchbase,请使用以下查询。

      SELECT t.*
      FROM default AS t USE KEYS ["11","22","67"];
      

      【讨论】:

      • 感谢您添加 cmets。但我想务实地获取使用 pouchDB 的文档
      • @KrunalLathia 由于您没有使用 Couchbase,我将删除您问题上的所有 Couchbase 标签。
      猜你喜欢
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      相关资源
      最近更新 更多