MongoDB: Search by id and other properties - mongodb

I have Mongo document
{
"_id" : ObjectId("5e4c4c0935f4115dfc5540c2"),
"code" : "ABC"
}
and as per other SO threads looks like doing regex on Id is not possible as it has hexString. So I am querying with ObjectId
#Query("{'code': {$regex : ?0, $options: 'i'}, '_id': ?1}")
Page<Pack> findByCodeAndId(String code, ObjectId objectId, Pageable pageable);
now as the query paramets or optional, I have check if the passed id is valid before converting it to ObjectId
ObjectId objectId = null;
if (ObjectId.isValid(id)) {
objectId = new ObjectId(id);
}
now for the request {code: null, id: null} I want to bring first 10 documents as these are optional but the query is not working when it is passed null as ObjectId
Also tried ObjectId objectId = new ObjectId() but it is generating a random haxString and giving empty records when id is null

Related

Mongoose $nin with array of ObjectId

I am facing a problem with mongoose. I can't do a query filter with $nin or $ne on an array of ObjectId.
Like:
query: {
objectIds: { $nin: [ objectId1, objectId2 ] }
}
I tried to send an ObjectId.toString(), an ObjectId, but nothing works.
However, if I replace the ObjectId array by a string array or put ObjectId in it, it works.
Any idea why it doesn't work with ObjectId?

exclude the fields when value is empty in mondodb match statement

i am writing a spring boot mongo query to fetch the results based name, csi, city. sometimes name, csi is empty in that case my query should not consider the fields which are empty. query should exclude the fields and incase data is there it suppose to fetch the results.
For Example
$match:{
name:'test',
csi:'' //exclude if blank or null,
city:'hyd'
}
my springboot query is but it is not ignoring the fields when empty
#Aggregation({
"{\"$match\": { \"$and\" : [ {\"name\" : { \"$ne\":\"\" }}, {\"name\" : ?0 }, {\"csi\" : { \"$ne\":\"\" }}, {\"csi\" : ?1 }, {\"city\" : { \"$ne\":\"\" }}, {\"city\" : ?2 }] }}"
})
List<data> getdata(String name, String csi, String city);

MongoDB: Filter on _id == obj._id without setting obj._id to null on insert

I'd like to configure an upsert. If _id already exists on my object, it recognizes that and updates the match. If _id doesn't exist, it should insert the new document and generate an _id. I'd expect { _id: obj._id } to work, but that overrides the auto-generation of _id. The document appears with _id: null. Is there a filter that would work for this? Do I need to route to insert/update in-code?
Edit: add query.
collection.updateOne(
{ _id: entity._id },
{ $set: entity },
{ upsert: true }
)
Edit: try delete.
Even when I delete the property, no luck.
const upsertTest = (collection) => {
const entity = { date: new Date() };
console.log(entity);
// { date: 2019-11-19T22:16:00.914Z }
const _id = entity._id;
delete entity._id;
console.log(entity);
// { date: 2019-11-19T22:16:00.914Z }
collection.updateOne(
{ _id: _id },
{ $set: entity },
{ upsert: true }
);
console.log(entity);
// { date: 2019-11-19T22:16:00.914Z }
}
But the new document is this:
screenshot of new document
You have to use $setOnInsert to Insert _id
let ObjectID = require('mongodb').ObjectID;
collection.updateOne(
{ _id: entity._id },
{ $set: entity,$setOnInsert:{_id:new ObjectID()}},
{ upsert: true }
)
As the name suggests it will set the _id on insert
If you are using mongodb then new ObjectID() should work,
If its mongoose then you can use mongoose.Types.ObjectId() to generate new ObjectID
Well I Found your Issue
Changed in version 3.0: When you execute an update() with upsert: true and the query matches no existing document, MongoDB will refuse to insert a new document if the query specifies conditions on the _id field.
So in a nutshell you cannot insert a new doc using upsert:true if your query is using _id, Reference
First of all, the _id property WILL always exist, whether you set it yourself or let it auto-generate. So there's no need to check if it exists.
The syntax for upsert is as follows:
db.collection.update({
_id: 'the id you want to check for' // can put any valid 'find' query here
}, {
$set: {
foo: 'bar',
biz: 'baz'
}
}, {
upsert: true
});
If a document with the given _id exists, it will be updated with the $set object. If it does not exist, a new one will be created with the properties of the $set object. If _id is not specified in the $set object, a new _id value will be auto-generated, or will keep using the existing _id value.
The key here is using $set, rather than putting the object right in there. Using set will merge and replace the properties. Without $set it will replace the entire document, removing any unset properties.
Edit: Now seeing the actual query you made, I would suggest you delete the _id property from the entity before setting it. This will make sure it is left alone.
const _id = entity._id;
delete entity._id;
// now do your query using the new `_id` value for the ID.
From our comments you mentioned you were using the local database. The local database allows _id to be null. Using any other DB should fix your issue.
If the entity._id is null then it will create a doc with _id null, We can solve this issue by adding Types.ObjectId(). If the _id doesn't exist then it will create a new document with the proper _id. otherwise, it will update the existing document.
const { Types } = require("mongoose")
collection.updateOne({ _id: Types.ObjectId(entity._id) },{ $set: entity },{ upsert: true})

how to get results from mongoDB where _id is string objectId

in my mongo database _id is string from ObjectId like this:
when I make this query I get results but with wrong sorting
db.collection.find({ _id : {$gt:"57c03e6288579757b5172d51"} });
how to fix that ?
You cannot query by inserting the objectID string with $gt operator.
You will have to create an objectID.
var objID = ObjectId("57c03e6288579757b5172d51");
db.collection.find({ _id : {$gt: objID} });
Documentation

mongodb: exclude documents that contain a particular attribute during query

I have a mongo collection with data as follows:
(userid, orgid, some_attr)
g#gmail.com, 12345, 'xxxxxx'
Same collection also contains:
(orgid, some_attr)
12345, 'yyyyy'
Now when I am updating data I may query on (userid, orgid) or (orgid).
My issue is:
when I update using query (orgid), it finds the record with userid and updates that. I dont want that.
How can I query on (orgid) but exclude all documents which contains
(userid, orgid).
For eg:
when I query { orgid : 12345 } it should only return { 12345, 'yyyyy' } and not
{ 'g#gmail.com' , 12345, 'xxxxx' }
Please provide pointers.
http://docs.mongodb.org/manual/reference/operator/query/exists/
Change your query:
{ orgid : 12345, userid: {$exists: false} }