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 andquery1
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
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 andquery1
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
Share Improve this question edited Feb 20, 2020 at 22:56 Unicornist 93213 silver badges22 bronze badges asked Apr 21, 2016 at 4:56 Himanshu GoyalHimanshu Goyal 1611 silver badge10 bronze badges 3- If you can, u may use lodash _.clone methods : lodash.com/docs#clone or lodash.com/docs#cloneDeep – mimiz Commented Apr 21, 2016 at 5:04
- you said Object.assign(query1).......is not working? can you mention what happened with that? – GvSharma Commented Apr 21, 2016 at 5:36
- @gvsharma change query1 reflects in query variable in this case. – Himanshu Goyal Commented Apr 21, 2016 at 5:58
5 Answers
Reset to default 8Alternative 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()])
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();
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;
});
}
Since mongoose v6 you can use Query.prototype.clone
E.g. for your code snippet:
const query = domain.User.find({
deleted: false,
role: role
})
const query1 = query.clone();
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()])