How to get specific data (from an Array) using PouchDB-Find
Asked Answered
O

1

7

CouchDB document:

  "members": [
    {
      "name": "Mark",
      "age": 35,
    },
    {
      "name": "Bill",
      "age": 32,
    }
  ]

DB Query from PouchDB using PouchDB-Find:

  db.createIndex({
    index: {fields: [
      '_id',
      'members.[].name'
    ]}
  }).then(() => {
    db.find({
      'selector': {
        '_id': { '$gt': null },
        'members': {
          '$elemMatch': {
            'name': {'$eq': 'Bill'}
          }
        }
      },
      'fields': [
        'members'
      ]
    }).then((result) => {
      console.log(result)
    }).catch((err) => {
      console.log(err)
    })
  })

The result I get from the above query is the Members array as the whole. But I need to get only the below when I request "name" as "Bill" not the complete array.

{
  "name": "Bill",
  "age": 32,
}

I did try the fields section in the query but I am unable to find what should be mentioned to get what I want.

Ostrom answered 27/9, 2018 at 8:3 Comment(0)
B
0

It is only possible to specify a set of index independent (static) fields in the doc for find to pick once your selector has chosen a given doc.

Mango queries are a simplified syntax to do common cases and when the structure of your indexes and queries is not typical, you need to use map/reduce directly as indicated in the docs:

The map/reduce API is designed for cases that are too complex for Mango queries

So your changes to the first map/reduce example would look something like:

function mapFun(doc) {
    if (doc.members)
      doc.members.forEach( function(m) {
        emit(m.name, m);  // key is name, value is the individual member Object
      });
  }.toString()
  ...
  return db.query('index', {
    key: 'Bill',
    include_docs: false
  });

To get output like:

 {
  "offset" : 0,
  "rows": [{
    "id": "somedoc",
    "key": "Bill",
    "value": {name:'Bill', age:32}
  }],
  "total_rows" : 1
}
Bulgar answered 3/10, 2018 at 19:27 Comment(2)
Can you check this example: nolanlawson.github.io/pouchdb-find and choose Select certain fields and then replace selector: {debut: {$gt: null}} with selector: {debut: {$eq: 1990}} This is what I am looking for, Can this be achieved with Mango Query if so how to design the DB like shown in the example. If not, I will go with the Map/Reduce query like you have advised. Thanks.Ostrom
@VijayRajasekaran since each item was its own doc in that example, it all works fine with find's lack of connection between using indexes for the query and then picking fields looking only at the each returned doc. To do what you want without either breaking up the docs or repeating your filters again externally on each returned document, you would need an index with 0 to many keys per doc where multiple keys for one doc each map to a different section of the document, I don't think you'll see anything like that in find's source nor access to the right primitives via createIndex.Bulgar

© 2022 - 2024 — McMap. All rights reserved.