I am using mongoDB database. in which I have collection in below format.
{ name : name1 , area: a , country : c}
{ name : name2 , area: b , country : c}
{ name : name3 , area: a1 , country : c1}
{ name : name4 , area: b1 , country : c1}
i want query like
select * from coll where (country =c and area =a) or (country = c1 and area = b1)
in mongodb query.
I have read many document but not found suitable answer.
So if any one knows please reply.
Thanks
By default, all elements in a mongodb query use the and operator. You can specify an or operator using the { "$or": [ ... ] } construct, as described in the documentation.
Your query will be :
{ "$or": [ { "country": "c", "area": "a" }, { "country": "c1", "area": "b1" } ] }
Related
There is a Student collection in my Database as below.
Mongodb Student Collection :
{
name : 'Rahul',
age : '15'
}
{
name : 'Ajay',
age : '25'
}
{
name : 'Pinku',
age : '43'
}
{
name : 'Vinod',
age : '30'
}
I am getting an array of data after making a callout to external system for the above students.
[
{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}
]
My task is to update the Students collection record, with the marks of matching student. Is there a way i can do it in one dml operation, instead of looping through each student document and updating it with marks.
Output should be:
Mongod Student Collection :
{
name : 'Rahul',
age : '15',
marks : 80
}
{
name : 'Ajay',
age : '25',
marks : 20
}
{
name : 'Pinku',
age : '43',
marks : 12
}
{
name : 'Vinod',
age : '30',
marks : 50
}
Note : I want to do this inside MondbDB Realm UI, to automate some functionality.
bulkWrite would be useful in this situation. Map over the input array to generate an array of updateOne operations, then submit them all in bulk.
let input = [
{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}
];
let operations = input.map(function(student){
return {updateOne:{filter:{name:student.name},update:{$set:{marks:student.marks}}
};
db.collection.bulkWrite(operations);
Query
pipeline update requires MongoDB >= 4.2
students-grades :
[{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}]
put this variable on reduce "input"
find the documents where name is in the array (its best to have an index on name)
instead of ["Ajay", "Pinku", "Vinod", "Rahul"] use something like
get-names(students-grades) with your driver code
$reduce the students-grades, to find for each name the mark
all have a mark because they passed the find
Test code here
update(
{"name": {"$in": ["Ajay", "Pinku", "Vinod", "Rahul"]}},
[{"$set":
{"mark":
{"$reduce":
{"input":
[{"name": "Ajay", "marks": 20}, {"name": "Pinku", "marks": 12},
{"name": "Vinod", "marks": 50}, {"name": "Rahul", "marks": 80}],
"initialValue": "$$REMOVE",
"in":
{"$cond":
[{"$eq": ["$$this.name", "$name"]},
"$$this.marks",
"$$value"]}}}}}],
{"multi": true})
let marksArr = [
{'name':'Ajay','marks':20},
{'name':'Pinku','marks':12},
{'name':'Vinod','marks':50},
{'name':'Rahul','marks':80}
]
for(let i = 0 ; i<marksArr.length ;i++){
let name = marksArr[i]['name']
let marks = marksArr[i]['marks']
let updateStudentData = await studentModel.update({name : name} , {marks : marks}, {new : true})
}
it's update student record after matching the name from marks table.
I'm new to MongoDB!
I need to extract all documents having the same Address, type, and id only. There will be only a single address in addresses. Others attributes can have different values. see below Test doc for example:
{
"Id" : "123",
"type" : "T1",
"addresses" : [
{
"address" : {
"line1" : "line 1 ...",
"line2" : "line 2...",
"state" : "state1...",
"city" : "city1...",
"zip" : "123456"
}
}
],
"email" : "test1#gmail.com",
"salary" : ""
}
For Example I've below documents, first value is type, second is id, third is address, fourth is email and so on:
doc1 - t1 1 address1 email1 ...
doc2 - t1 2 address2 email2 ...
doc3 - t1 1 address1 email3 ...
doc4 - t1 1 address1 email4 ...
doc5 - t1 2 address2 email5 ...
doc6 - t1 1 address1 email6 ...
outcome: [ [doc1, doc3, doc4, doc6], [doc2, doc5] ]
Here doc1, doc3, doc4, doc6 having the same id, type, and address. And doc2, doc5 having the same id, type, and address.
Could anyone please suggest how to achieve this in MongoDB?
After reading the Mongo aggregation framework and some R&D, I was able to achieve this using below approach:
db.getCollection('test_collection').aggregate([
{
$group: {
_id: { type: "$type", id:"$Id", line1: "$addresses.0.address.line1" ... },
docGroups: { $addToSet: "$$ROOT" }
}
}
]);
I have a collection of like so :
db.records.save( {
name : "John Smith",
addresses : [ {
context : "home" ,
loc : [ 55.5, 42.3 ]
} ,
{
context : "work",
loc : [ -74 , 44.74 ]
}
]
} )
And I've created an index like this:
db.records.createIndex( { "addresses.loc": "2d" } )
Now when I try and make a query like:
db.Company.findOne({ "stores.loc" : { $near :[55.5, 42.3]}})
What I expect to get is john smite with an array of addresses with only the relevant address, what I get is john smite with all of the addresses, So I do not know.
How do I solve this?
This can be fixed if you can alter your schema to take one address in a document and get nearest node from there then:
db.records.save( {
name : "John Smith",
address_context: "home",
address_loc : [ 55.5, 42.3 ]
} )
db.records.save( {
name : "John Smith",
address_context: "work",
address_loc : [ -74 , 44.74 ]
} )
Now create a index on address_loc and query, you will get relevant nearest nodes
I'm using Mongoose and have a schema like this:
var chat = new mongoose.Schema({
chatId : String,
members : [{
id : String,
name : String
}]
});
Suppose I have two chat document like this
{
chatId : 'Edcjjb',
members : [
{
id : 'a1',
name : 'aaa'
},
{
id : 'b1',
name : 'bbb'
}
]
}
{
chatId : 'Fxcjjb',
members : [
{
id : 'a1',
name : 'aaa'
},
{
id : 'b1',
name : 'bbb'
},
{
id : 'c1',
name : 'ccc'
}
]
}
I want to find all those documents which have only specfied members Id.
For example, if I specify a1 and b1
then only the first document should be retrieved as the second document contains id c1 as well.
And if I specifiy a1,b1,c1
then only second document should be specified.
Please tell me how to do this in mongoose
You can specify a clause on the array size, like
{ members : { $size : 2 } } in your first example and
{ members : { $size : 3 } } in the second one.
Can that work for you?
EDIT: I should also mention that the other part of the query should be
{ "members.id": { $all: [ "a1" , "b1" ] } }
and, for the second example,
{ "members.id": { $all: [ "a1" , "b1", "c1" ] } }
So, what I'm trying to do is query all documents that have a City of 'Paris' and a State of 'France'. I need to do some kind of join, but I haven't been able to figure out how to construct it.
I'm using the c# driver, but I'll gladly accept help using any method.
{
"_id" : ObjectId("519b407f3c22a73a7c29269f"),
"DocumentID" : "1",
"Meta" : [{
"Name" : "City",
"Value" : "Paris",
}, {
"Name" : "State",
"Value" : "France",
}
}]
}
{
"_id" : ObjectId("519b407f3c22a73a7c29269g"),
"DocumentID" : "2",
"Meta" : [{
"Name" : "City",
"Value" : "Paris",
}, {
"Name" : "State",
"Value" : "Texas",
}
}]
}
The $elemMatch operator is used to indicate that all the conditions within it must be matched by the same array element. So (to switch to shell syntax) to match all documents which have meta city Paris you would do
db.collection.find( {Meta:{$elemMatch:{Name:"City",Value:"Paris"}}} )
This assures you won't match something which has Name: "somethingelse", Value: "Paris" somewhere in its array with a different array element matching the Name:"City".
Now, default combination for combining query conditions is "and" so you can continue adding attributes:
db.collection.find( {Meta: {
$elemMatch:{Name:"City",Value:"Paris"},
$elemMatch:{Name:"State",Value:"France"}
}
}
)
Now if you want to add another condition you keep adding it but if you want a NOT then you do it like this:
db.collection.find( {Meta: {
$elemMatch:{Name:"City",Value:"Paris"},
$elemMatch:{Name:"State",Value:"France"},
$not: {$elemMatch:{Name:"Arrondissement",Value:"Louvre"}}
}
}
)
I might be answering my own question here, but I'm new to MongoDB, so while this appears to give me the results I'm after, it might not be the optimum approach.
var result = collection.Find(
Query.And(
Query.ElemMatch("Meta", Query.EQ("Name", "City")),
Query.ElemMatch("Meta", Query.EQ("Value", "Paris")),
Query.ElemMatch("Meta", Query.EQ("Name", "State")),
Query.ElemMatch("Meta", Query.EQ("Value", "France")))
);
Which leads to a follow up - how would I get all of the documents whose 'City' is 'Paris' and 'State' is 'France' but whose 'Arrondissement' is not 'Louvre'?