Nested Mongo Query from CLI - mongodb

For the following data (taken from MongoDB in Action), how can I query in Mongo Shell to get the addresses.street for any document (in my case it's only 1 here) where the addresses.home equals "home"?
Desired result: {"street" : "1 E. 23rd Street"}
{ _id: ObjectId("4c4b1476238d3b4dd5000001")
username: "kbanker",
addresses: [
{
name: "home",
street: "588 5th Street",
city: "Brooklyn",
state: "NY",
zip: 11215},
{
name: "work",
street: "1 E. 23rd Street",
city: "New York",
state "NY",
zip 10010},
]}

You have to use $elemMatch in projection mode : DOCS
db.collection.find({},{addresses: {$elemMatch:{'name':'home'}}, 'addresses.street':1, _id:0})
{ "addresses" : [ { "street" : "588 5th Street" } ] }

Related

MongoDB text search string equality?

I'm new to MongoDB and was looking through the docs a few nights ago and saw something that I haven't been able to locate since...
There was an option, I believe it was related to $text search, to treat an array of strings as if they were the same word. The syntax looked something like this:
["cheez", "cheese"],
["donut", "doughnut"],
["chips", "fries", "crisps"],
So a search for "chips" would return all documents indexed with "fries" or "crisps" even if they did not also have "chips".
Please tell me I wasn't dreaming!
YOU ARE NOT DREAMING
mongodb fuzzy text search
The following query searches the title field for the phrase naw yark. It uses the fuzzy default options where:
maxEdits allows up to two character variation of each term in the
given phrase to match the query to a document.
maxExpansions considers up to fifty similar terms for each term in
naw yark to find matches.
prefixLength is disabled.
The query also includes a $limit stage to limit the output to 10 results and a $project stage to:
Exclude all fields except title
Add a field named score
db.movies.aggregate([
{
$search: {
"text": {
"path": "title",
"query": "naw yark",
"fuzzy": {}
}
}
},
{
$limit: 10
},
{
$project: {
"_id": 0,
"title": 1,
score: { $meta: "searchScore" }
}
}
])
The above query returns the following results:
{ "title" : "New York, New York", "score" : 4.392756462097168 }
{ "title" : "New York", "score" : 4.050914287567139 }
{ "title" : "New York Stories", "score" : 3.4838104248046875 }
{ "title" : "New York Minute", "score" : 3.4838104248046875 }
{ "title" : "Synecdoche, New York", "score" : 3.4838104248046875 }
{ "title" : "New York Doll", "score" : 3.4838104248046875 }
{ "title" : "Little New York", "score" : 3.4838104248046875 }
{ "title" : "Escape from New York", "score" : 3.0559897422790527 }
{ "title" : "King of New York", "score" : 3.0559897422790527 }
{ "title" : "Naked in New York", "score" : 3.0559897422790527 }
also synonyms:
mongodb synonyms text search

Calculate the average value of a mongodb document [duplicate]

This question already has answers here:
Mongo average aggregation query with no group
(3 answers)
Closed 7 years ago.
Suppose that I have a collection like this:
{
_id: 1,
city: "New York",
state: "NY",
murders: 328
}
{
_id: 2,
city: "Los Angeles",
state: "CA",
murders: 328
}
...
The collection shows us the number of murders in all cities of USA. I'd like to calculate the average of murders in all the country. I tried to use
$group:
db.murders.aggregate([{$group: {_id:"$state", pop: {$avg:"$murders"} } }])
But I get as result the murders by state:
{ "_id" : "NY", "murders" : 200 }
{ "_id" : "NJ", "murders" : 150 }
{ "_id" : "CA", "murders" : 230 }
{ "_id" : "CT", "murders" : 120 }
My question is, how can I group this result to calculate an unique average? Something like this:
{ "_id" : "USA", "murders" : 175 }
Try grouping by null.
db.murders.aggregate([{$group: {_id:null, pop: {$avg:"$murders"} } }])
More-Info: mongo-average-aggregation-query-with-no-group

mongo insert object if not present in doc in meteor

I have this obj
I have existing record
{
"_id":"xxxx",
"industry" : "Information Technology and Services",
"name" : "dsdds",
"profession" : "Information Technology and Services Profession Two",
"self_employed" : true,
"sex" : "M"
}
I want to update the object with {loc:"sss",db:"sss",bio:"fsdf"} as profile object like below
{
"user_id":"xxxx",
"industry" : "Information Technology and Services",
"name" : "dsdds",
"profession" : "Information Technology and Services Profession Two",
"self_employed" : true,
"sex" : "M",
"profile":{loc:"sss",db:"sss",bio:"fsdf"}
}
I tried with this
User.update({user_id:"xxxx"},{$set:{"profile":{user:"ssa",sss:"dsd"}}})
User.update({user_id:"xxxx"},{$set:{"profile":profile}})
both are returning 1 but not inserting record.
what is wrong in my command?
In my terminal
User.update({user_id:"JvH4YMBJmZrKWPhig"},{$set:{"profile":{user:"ssa",sss:"dsd"}}})
1
> User.findOne({user_id:"JvH4YMBJmZrKWPhig"})
{ _id: 'ye4uzZYXT5PCtcNrs',
company: 'ghghfh',
dob: '703621800',
hubs: [ 'AcztzE8W3hFTeTyz8' ],
industry: 'Computer Software',
job_title: 'Software Engineer',
name: 'ss',
profession: 'Computer Software Profession One',
self_employed: false,
sex: 'M',
user_id: 'JvH4YMBJmZrKWPhig' }
Try with
var finde = User.findOne({user_id:"JvH4YMBJmZrKWPhig"})
So try with one of this.
Meteor.users.update({_id:finde._id}, {$set: {profile: {value1: 'value1', value2: 'value2'}}});
or if you are using another Collection different to Accounts users
Using object on the update.
var values = {
value:"value1",
value2:"value2"
}
User.update({_id:finde._id},{$set: {profile: {values}}});

Mongo update based on array index

I have a list of people in my database, where each person is one document. I would like to give them standard names (this is just for demo purposes – I don't care who gets which name so long as its unique).
I have an array of names to give them but I am not sure how to do this in Mongo. One simple way would be to just have a cursor and update the documents one by one, but that seems inefficient. Is there a better way to do this?
EDIT:
example db:
{id: 1234, age: 50}
{id: 1235, age: 40}
{id: 1236, age: 30}
Names:
['Bob', 'Jill', 'Gina']
Desired end state:
{id: 1234, age: 50, name: 'Bob'}
{id: 1235, age: 40, name: 'Jill'}
{id: 1236, age: 30, name: 'Gina'}
I'm not sure how you are specifying which names go with which _ids, so I'm going to assume you have a mapping specified in the following form:
> nameMapping
[{ "_id" : 1234, "name" : "Bob" }, { "_id" : 1235, "name" : "Jill" }, { "_id" : 1236, "name" : "Gina" }]
Then a good way to update every doc with a name is to use bulk operations. Bulk operations are supported in the drivers but I'll give the example in the mongo shell with bulk.find.update(), which is available as of MongoDB 2.6.
> var bulk = db.people.initializeUnorderedBulkOp()
> nameMapping.forEach(function(pair) {
bulk.find( { "_id" : pair._id } ).update( { $set: { "name" : pair.name } } )
})
> bulk.execute()

Spring Data MongoDB Index Query on Sub Document

In the MongoDB Documentation we've got the following example:
db.factories.insert( { name: "xyz", metro: { city: "New York", state: "NY" } } );
db.factories.ensureIndex( { metro : 1 } );
// this query can use the above index:
db.factories.find( { metro: { city: "New York", state: "NY" } } );
I'm currently looking for a solution to archieve this query in spring data. My first approach was
Query.query(Criteria.where("metro")
.andOperator(Criteria.where("city").is("New York")
.and("state").is("NY")))
but this results in the following query
{ "metro" : { } , "$and" : [ { "city" : "New York" , "state" : "NY"}]}
Finally i found the solution by fiddling around:
Query.query(Criteria.where("metro").is(
Query.query(
Criteria.where("city").is("New York")
.and("state").is("NY")).getQueryObject()
)
)
// results in { metro: { city: "New York", state: "NY" } }
Hopefully this is the right way to do it...