简体   繁体   中英

how to clone the mongoose query object in javascript

I am facing the problem of clone of the mongoose query object . Javascript the copy the one object into another object by call-by-ref but in my project there is scenario i need to copy one object into another object by call-by-value.

    var query=domain.User.find({
            deleted: false,
            role: role
        })

var query1=query;

I have the scenario change in the query object is not reflected in query1 . I google and try so many way to clone the object but it does't work.The query object is used in another function for pagination and query1 object is used for count query.

1.I used to Object.clone(query1) error Object.clone is not function 2.I used Object.assign(query1) but it does't works fine. 3.I used other so many ways can anybody help me to sort this problem

you are trying to clone a cursor, but it is not the right approach, you probably just need to create another

like this:

var buildQuery = function() {
  return domain.User.find({
    deleted: false,
    role: role
  });
};

var query = buildQuery();
var query1 = buildQuery();

Alternative solution using merge method:

const query = domain.User.find({
  deleted: false,
  role: role
}).skip(10).limit(10)

const countQuery = query.model.find().merge(query).skip(0).limit(0)

const [users, count] = await Promise.all([query, countQuery.count()])

This is work for me:

const qc = sourceQuery.toConstructor();
const clonedQuery = new qc();

This code work in pagination function where sourceQuery passed as parameter and i dont known what models used. Also it work with aggregations and complex queries.

  public async paging(
    query: mongoose.DocumentQuery<mongoose.Document[], mongoose.Document>,
    params,
    transformer: any = null
  ) {
    let page = Number(params.page);
    if (!page) page = 1;

    let page_size = Number(params.count);
    if (!page_size) page_size = 100;

    const qc = query.toConstructor();
    const cq = new qc();
    return cq.countDocuments().exec()
      .then(async (total) => {
        const s = params.sort;
        if (s) {
          query.sort(s);
        }
        query.limit(page_size);
        query.skip(page_size * (page - 1));
        let results = await query.exec();
        if (transformer) {
          results = await Promise.all(results.map((i) => transformer(i)));
        }
        const r = new DtoCollection();
        r.pages = Math.ceil(total / page_size);
        r.total = total;
        (r.results as any) = results;
        return r;
      });
  }

Sergii Stotskyi's answer works just fine and is very elegant, except that count is deprecated.

countDocuments or estimatedDocumentCount should be used instead.

However, this causes the error the limit must be positive . We can walk around this by set limit to a large integer.

const query = domain.User.find({
  deleted: false,
  role: role
}).skip(10).limit(10)

const countQuery = query.model.find().merge(query).skip(0).limit(Number.MAX_SAFE_INTEGER)

const [users, count] = await Promise.all([query, countQuery.countDocuments()])

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