简体   繁体   中英

MongoDB get total count aggregation pipeline with $search

I have to implement search using search indexes in MongoDB Atlas as well as normal browse feature. This includes filtering, match, sort, skip, limit (pagination). I have made an aggregation pipeline to achieve all this. First I push the search query to my pipeline, then match, then sort, then skip and finally the limit query.

Here's how it goes:

query = [];
query.push({
    $search: {
      index: 'default'
      text: {
        query: searchQuery
        path: {  }
      }
    }
  });
 query.push({
      $sort: sort,
    });
 query.push({
    $match: {
      type: match
    },

query.push({
  $skip: skip
});
query.push({
  $limit: perPage
});

let documents = await collection.aggregate(query);

The results I get so far are correct. However, for pagination, I also want to get the total count of documents. The count must take the "match" and "searchQuery" (if any) take into account. I have tried $facet but it gives error $_internalSearchMongotRemote is not allowed to be used within a $facet stage

So, I see a few challenges with this query.

  1. The $sort stage may not be needed. All search queries are sorted by relevance score by default. If you need to sort on some other criterion, then it may be appropriate.

  2. The $match stage is probably not needed. What most people are looking for when they are trying to match is a compound filter. As you can see from the docs , a filter behaves like a $match in ordinary MongoDB. From where I am, your query should probably look something like:

If you would like a fast count of the documents returned, you need to use the new count operator. It is available on 4.4.11 and 5.0.4 clusters. You can read about it here .


query = [];
query.push({
    $search: {
      index: 'default'
      "compound": {
      "filter": [{
        "text": {
          "query": match,
          "path": type
        }
      }],
      "must": [{
        "text": {
          "query": searchQuery,
          "path": { }
        }
      }]
    }, 
     "count": {
      "type": "total"
     }
   }
  });

query.push({
  $skip: skip
});

query.push({
  $limit: perPage
});

let documents = await collection.aggregate(query);



  [1]: https://docs.atlas.mongodb.com/reference/atlas-search/compound/#mongodb-data-filter
  [2]: https://docs.atlas.mongodb.com/reference/atlas-search/counting/#std-label-count-ref

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM