mongodb geospatial query for multyindex data - mongodb

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

Related

I am new to mongoDB need a query to delete the collections

I have two collections.
1.Equipment
db.getCollection("Equipment").find({
$and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]})
{
"_id" : "1234567",
"locationId" : "DATALOAD",
"model" : "A505",
"subscriberId" : "",
"status" : "Stock",
"headendNumber" : "4"
}
{
"_id" : "P13050I",
"locationId" : "1423110302801",
"model" : "A505",
"subscriberId" : "37",
"status" : "Stock",
"headendNumber" : "4"
}
I will get more than 100 documents (rows) Equipment collection.
2.Subscriber
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"1234567",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"P13050I",
"M91416EA4251",
"128552270280560"
]
}
In the Subscriber collection, I need to remove (get all the id from Equipment collection loop it) only the matches equipment field.
Forex from the above result, I need to remove only "1234567", and "P13050I"
Expected output.
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"M91416EA4251",
"128552270280560"
]
}
Please help me, anyone.
You can use the following to update records.
Let's find records which need to deleted and store them in array
var equipments = [];
db.getCollection("Equipment").find({ $and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]}).forEach(function(item) => {
equipments.push(item._id)
})
Now, iterate over records of the second collection and update if required.
db.getCollection('Subscriber').find({}).forEach(function(document) => {
var filtered = document.equiment.filter(id => equipments.indexOf(id) < 0);
if(filtered.length < document.equipment.length){
db.getCollection('Subscriber').update({"_id": document.id }, { $set: {'equipment': filtered}})
}
})
.filter(id => equipments.indexOf(id) < 0) will keep entries which is not present in initially populated array equipments and it will persist if there is any change.

mongodb how to display Null or none for a field instead of it being blank

The query below will show me the names of people and all their details. Some have addresses, some have not. It shows the addresses where they exist. What do I use if I wanted to show "addresses: "none" " where there are none given? I am also trying to sort by name.
db.test.find({name:{$exists:true}}, {_id:0}, {$sort:{"name":1}})
So far I can select the ones which have names, hide the _id column from view and sort by name. All the addresses (where they exist) are given. It is the "addresses: none" I am finding tricky.
Any pointers? Thank you.
test collection with the following documents
{"_id" : 1, "name" : "Thyame", "address": "Kapan" },
{"_id" : 2, "name" : "Diple", "address": null },
{"_id" : 3, "name" : "Sid" }
and Query is
db.test.aggregate
(
[
{
$project: {
address: { $ifNull: [ "$address", "Null" ] }
}
}
]
);

How to update document with nested array in mongodb [duplicate]

This question already has answers here:
Mongodb $push in nested array
(4 answers)
Closed 4 years ago.
I've got a document in a collection 'events' with the following structure:
{
"_id" : "abc",
"text" : "some text",
}
I wish to update the document by inserting an array named guestOwner. The result I want would update the document like this:
{
"_id" : "abc",
"text" : "some text",
"guestOwner" : [
{
"name" : "JACK BLACK",
"guests" : [
"GUEST1",
"GUEST2"
]
}
]
}
So I tried an mongo update with the following:
db.events.update({ _id: eventid }, { $push: { guestOwner: { name: username, guests: allGuests } } });
where 'username' is a string, and 'allGuests' is an array of names ["Guest1", "Guest2"]
The issue for me is when a subsequent update to the document occurs, I would want to push a the new 'allGuests' array into the existing one if the name is the same. For example, if a second update occurs with 'allGuests' = ["GUEST3"], and with the same name = "JACK BLACK", I would want the document to be:
{
"_id" : "abc",
"text" : "some text",
"guestOwner" : [
{
"name" : "JACK BLACK",
"guests" : [
"GUEST1",
"GUEST2"
"GUEST3"
]
}
]
}
BUT, if the document were updated with a different name = 'JOHN SMITH' where allGuests array = ["GUEST3"], it would create:
{
"_id" : "abc",
"text" : "some text",
"guestOwner" : [
{
"name" : "JACK BLACK",
"guests" : [
"GUEST1",
"GUEST2"
]
},
{
"name" : "JOHN SMITH",
"guests" : [
"GUEST3"
]
}
]
}
Would I need conditional statements surrounding the mongo update to check for guestOwner[0].name? Not sure if mongo could do this on its own, or if a bunch of logic is going to be necessary.
You could simply do an update where in the query section you would specify the name:
db.events.update({
"_id" : ObjectId("someId"), "guestOwner.name": "JACK BLACK"}, {
$push: { "guestOwner.$.guests": "GUEST11" // etc }
})
If this returns the number of updated elements to be 1 you are good to go since the name exists etc.
If it returns 0 then that name does not exists so you can run:
db.events.update({"_id" : ObjectId("someId")}, {
$addToSet: { guestOwner: { name: "JACK BLACK" // etc }}
})
It would save you one call since if you have to check if the record exists you would always do 2 rounds. One to check and another to take action based on the result. Here if the records is already there you only do one update.

How to Create an index of a key in a map or item in a list in MongoDB

The following questions refer to my example.
How do I create an index for the ids in idsAndNames map?
I want to search these numbers: 7065362, 7064458, 7065003, 7064286...
How do I create an index for the strings in subTargets list?
I want to search these strings: ALL, ACTION, DRAMA...
My example:
{
"_id" : ObjectId("sdfsdfsdfsdfsdfsd910d41ad9"),
"targets" : {
"Superheroes" : {
"idsAndNames" : {
"7065362" : "Doctor Strange",
"7064458" : "Dr. Manhattan",
"7065003" : "Captain Atom",
"7064286" : "Hulk"
},
"subTargets" : [
"ALL",
"ACTION",
"DRAMA"
]
}
"BestSuperheroes" : {
"idsAndNames" : {
"7065362" : "Superman",
"7064458" : "Thor",
"7065003" : "Professor X",
"7064286" : "Batman"
},
"subTargets" : [
"ALL",
"SCIFI",
"CHICKFLICKS"
]
}
}
...
}
Before trying to create an index maybe you should review your schema, changing it to something like:
...
"Superheores" : [
{
"id": "7065362",
"name": "Doctor Strange"
}]
So you can use db.collection.ensureIndex({'targets.Superheroes.id': 1});. You won't be able to create an effective index if you have dynamic key names.
And for the text, you could try the text search index.

Updating an array of objects with a new key in mongoDB

Similar to this question
Barrowing the data set, I have something similar to this:
{
'user_id':'{1231mjnD-32JIjn-3213}',
'name':'John',
'campaigns':
[
{
'campaign_id':3221,
'start_date':'12-01-2012',
},
{
'campaign_id':3222,
'start_date':'13-01-2012',
}
]
}
And I want to add a new key in the campaigns like so:
{
'user_id':'{1231mjnD-32JIjn-3213}',
'name':'John',
'campaigns':
[
{
'campaign_id':3221,
'start_date':'12-01-2012',
'worker_id': '00000'
},
{
'campaign_id':3222,
'start_date':'13-01-2012',
'worker_id': '00000'
}
]
}
How to insert/update a new key into an array of objects?
I want to add a new key into every object inside the array with a default value of 00000.
I have tried:
db.test.update({}, {$set: {'campaigns.worker_id': 00000}}, true, true)
db.test.update({}, {$set: {campaigns: {worker_id': 00000}}}, true, true)
Any suggestions?
I'm supposing that this operation will occur once, so you can use a script to handle it:
var docs = db.test.find();
for(var i in docs) {
var document = docs[i];
for(var j in document.campaigns) {
var campaign = document.campaigns[j];
campaign.worker_id = '00000';
}
db.test.save(document);
}
The script will iterate over all documents in your collection then over all campaigns in each document, setting the *worker_id* property.
At the end, each document is persisted.
db.test.update({}, {$set: {'campaigns.0.worker_id': 00000}}, true, true
this will update 0 element.
if you want to add a new key into every object inside the array you should use:
$unwind
example:
{
title : "this is my title" ,
author : "bob" ,
posted : new Date() ,
pageViews : 5 ,
tags : [ "fun" , "good" , "fun" ] ,
comments : [
{ author :"joe" , text : "this is cool" } ,
{ author :"sam" , text : "this is bad" }
],
other : { foo : 5 }
}
unwinding tags
db.article.aggregate(
{ $project : {
author : 1 ,
title : 1 ,
tags : 1
}},
{ $unwind : "$tags" }
);
result:
{
"result" : [
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "fun"
},
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "good"
},
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "fun"
}
],
"OK" : 1
}
After you could write simple updaiting query.