Mongo: search sub array - mongodb

Looking for users that are a part of a group.
Here is one user:
meteor:PRIMARY> db.users.find({_id:"rYHRMPpdXRa8fPXrj"})
Here is the result the single user:
{ "_id" : "rYHRMPpdXRa8fPXrj", "profile" : { "firstName" : "C", "groups" : [ "GJcqFCnSzfvJbuTMS", "gxD85kTiXmbtwaKfo" ]}
I try to find...
db.users.find({"groups":"rYHRMPpdXRa8fPXrj"})
db.users.find({"profile.groups":"rYHRMPpdXRa8fPXrj"})
db.users.find({profile:{"groups":"rYHRMPpdXRa8fPXrj"}})
db.users.find({"profile":{"groups":"rYHRMPpdXRa8fPXrj"}})
db.users.find({"profile":{"groups":["rYHRMPpdXRa8fPXrj"]}})
db.users.find({profile:{"groups":"rYHRMPpdXRa8fPXrj"}})
db.users.find({profile:{groups:"rYHRMPpdXRa8fPXrj"}})
db.users.find({profile:{groups:["rYHRMPpdXRa8fPXrj"]}})
db.users.find({profile:{$elemMatch:{groups:["rYHRMPpdXRa8fPXrj"]}}})
db.users.find({profile:{$elemMatch:{groups:"rYHRMPpdXRa8fPXrj"}}})
db.users.find({profile:{groups:{$in:["rYHRMPpdXRa8fPXrj"]}}})
I get nothing. ARRRG!!
How do I find all users in a specific profile.group?

You are passing your user _id into your query instead of the group id(?).
Try:
db.users.find({"profile.groups":"GJcqFCnSzfvJbuTMS"})
for example

$all should be used to filter by items within array:
db.users.find({profile:{groups:{$all:["rYHRMPpdXRa8fPXrj"]}}})

Related

Mongo db query where condition for a column (list of values) having a value

I am trying to find a way to filter the records in Mongo db using Spring query.
Here is the scenario, let's see I have an Activity entity/document. One of the fields is a list of names. I want to see if I can get all the records that the names field includes get given value, let's say "Joker".
For example, my json in Mongo is
Activity 1 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445354"),
...
"names" : [{
"username" : "username1",
"realname" : "Super Man"
}, {
"username" : "username2",
"realname" : "Iron Man"
}]
}
Activity 2 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445355"),
...
"names" : [{
"username" : "username3",
"realname" : "Bat Man"
}, {
"username" : "username4",
"realname" : "Joker"
}]
}
And I expect the query will let me get Activity 2 only.
Also, if possible, I prefer to use spring Mongo query in my code. Thanks in advance.
Try
db.collection.find({"names.realname": "Joker"});
I never used Spring query but should be something like
Query query = new Query();
query.addCriteria(Criteria.where("names.realname").is("Joker"));
List<MyClass> users = mongoTemplate.find(query, MyClass.class);

Search through a collection for documents which have a partial string in an array of strings

I've got a collection which has a bunch of documents which look like this:
{
"_id" : ObjectId("58d1d3e2b31da89828d0b194"),
"ihash" : "15e1e4b84492fe6f",
"firstseen" : ISODate("2017-03-22T01:31:14.405Z"),
"lastseen" : ISODate("2017-03-22T14:01:25.792Z"),
"names" : [
"carrot",
"apple",
"banana"
]
}
and I want to search through my collection to find all documents which contain "rr" in the list of names.
Any help with this would be great :)
You can use a mongo regex (see https://docs.mongodb.com/manual/reference/operator/query/regex/).
From the mongo console:
db.collection.find({ "names" : /rr/ })
or alternatively
db.collection.find({ "names" : {"$regex": /rr/ }})
You may want to check out the documentation for other options that are supported such as case-insensitive, matching anchors (^ for the start, $ for the end of the string), and others if your needs require it.

Meteor/Mongo nested arrays update

I'm new to meteor/mongo/js as a stack and I'm getting lost in JSON arrays and referencing them. Based another SO answer ( and the docs) I think I am close...
A document in the Orders collection, the document has nested arrays.
Order -> orderLines -> lineItems:
Sample doc:
{
"_id" : "27tGpRtMWYqPpFkDN",
"orderLines" : [
{
"lineId" : 1,
"name" : "Cheese & Pickle",
"instructions" : "",
"lineItems" : [
{
"name" : "Cheddar Cheese",
"quantity" : 1
},
{
"name" : "Branston Pickle",
"quantity" : 1
},
{
"name" : "Focaccia Roll",
"quantity" : 1
}
]
}
]
}
What I'm trying to do from the meteor/mongo shell:
Add "instructions" of "foo" to orderLines where lineId = 1
Put a new item on lineItems array
This appears to hang...
meteor:PRIMARY> db.orders.update({_id:"27tGpRtMWYqPpFkDN","orderLines.lineId":"1", {$set: {"orderLines.$.instructions":"foo"}})
...
This doesn't like the identifier in the query
meteor:PRIMARY> db.orders.update({_id:"27tGpRtMWYqPpFkDN", "orderLines.lineId":"1"}, {$push:{"orderLines.$.lineItems":" { "name" : "butter", "quantity" : 1}"}});
2015-10-27T16:09:54.489+0100 SyntaxError: Unexpected identifier
Thanks all for your comments... but I found out some answers, posted for reference
Item 1 - using $set on a value within an array
This was failing due to two typos, one missing closing } at the end of the query, second was quoting the value "1" for itemId in the query.
This works:
db.orders.update({_id:"27tGpRtMWYqPpFkDN", orderLines.lineId":1},
{$set: {"orderLines.$.instructions":"foo"}})
I also realised that when I said "It appears to hang" it is the cli waiting for a valid statement, so hints at a missing } or )!
Item 2 - using $push to add data to an array - 2 levels nested
This was failing due to quoting around the array data
db.orders.update({_id:"27tGpRtMWYqPpFkDN", "orderLines.lineId":1 },
{$push:{"orderLines.$.lineItems": { "name" : "butter", "quantity" : 1} }})
Nested Arrays: can use $ positional operator
What I want to do next is use $set on an item in the second level array, and this would require using the $ positional operator twice:
db.orders.update({"orderLines.lineId":1, lineItems.name:"Cheddar Cheese"},
{$set: {"orderLines.$.lineItems.$.quantity": 2}})
This throws an error:
Too many positional (i.e. '$') elements found in path
There is an open MongoDB enhancement request for this but it's been open since 2010
$push adds a new element to an array. You're merely trying to set the value of a particular key in an array element.
Try:
db.orders.update({ _id: "27tGpRtMWYqPpFkDN", "orderLines.lineId": 1},
{ $set: { "orderlines.$.instructions": "foo" }})
docs

I have big database on mongodb and can't find and use my info

This my code:
db.test.find() {
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"title" : "Sir",
"name" : {
"_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
"first_name" : "Farid"
},
"addresses" : [
{
"city" : "Baku",
"country" : "Azerbaijan"
},{
"city" : "Susha",
"country" : "Azerbaijan"
},{
"city" : "Istanbul",
"country" : "Turkey"
}
]
}
I want get output only all city. Or I want get output only all country. How can i do it?
I'm not 100% about your code example, because if your 'find' by ID there's no need to search by anything else... but I wonder whether the following can help:
db.test.insert({name:'farid', addresses:[
{"city":"Baku", "country":"Azerbaijan"},
{"city":"Susha", "country":"Azerbaijan"},
{"city" : "Istanbul","country" : "Turkey"}
]});
db.test.insert({name:'elena', addresses:[
{"city" : "Ankara","country" : "Turkey"},
{"city":"Baku", "country":"Azerbaijan"}
]});
Then the following will show all countries:
db.test.aggregate(
{$unwind: "$addresses"},
{$group: {_id:"$country", countries:{$addToSet:"$addresses.country"}}}
);
result will be
{ "result" : [
{ "_id" : null,
"countries" : [ "Turkey", "Azerbaijan"]
}
],
"ok" : 1
}
Maybe there are other ways, but that's one I know.
With 'cities' you might want to take more care (because I know cities with the same name in different countries...).
Based on your question, there may be two underlying issues here:
First, it looks like you are trying to query a Collection called "test". Often times, "test" is the name of an actual database you are using. My concern, then, is that you are trying to query the database "test" to find any collections that have the key "city" or "country" on any of the internal documents. If this is the case, what you actually need to do is identify all of the collections in your database, and search them individually to see if any of these collections contain documents that include the keys you are looking for.
(For more information on how the db.collection.find() method works, check the MongoDB documentation here: http://docs.mongodb.org/manual/reference/method/db.collection.find/#db.collection.find)
Second, if this is actually what you are trying to do, all you need to for each collection is define a query that only returns the key of the document you are looking for. If you get more than 0 results from the query, you know documents have the "city" key. If they don't return results, you can ignore these collections. One caveat here is if data about "city" is in embedded documents within a collection. If this is the case, you may actually need to have some idea of which embedded documents may contain the key you are looking for.

Mongo Array in Array Query

Given the below example record, how can I find all users that belong to at least one group from an arbitrary set of groups to query against? For example, find all users that belong to any one of the following groups - 1, 10, 43. I'm looking for a generalized solution. I know I can build out an or query but is there a more efficient way to handle this?
> db.users.findOne()
{
"_id" : ObjectId("508f477aca442be537000000"),
"name" : "Some Name",
"email" : "some#email.com",
"groups" : [
1,5,10
]
}
{ groups: {$in: [1, 10, 43]} }