MongoHub remove data - mongodb

Looked everywhere online and can't find a simple answer to how to delete an id from MongoDB using MongoHUB.
In MongoHub I click on remove and i get presented with this above the query box:
db.site.markets.remove()
i want to remove this data:
{
"_id": 10,
"item": "box",
"qty": 20
}
Surely this code should work?
db.site.markets.remove(item : 'box' )
or
db.site.markets.remove(_id : 10)
Both of them don't work.
I'm making this too difficult... Stupid though it may sound a right click, delete function would be helpful...

When removing using mongohub you must wrap the parameters in quotes.
{"item" : "box"}
Also when removing by mongodb built in id the ObjectId() function is also required.
{ "_id" : ObjectId( "12345")}

You should give an object to mongodb. And _id column generated by mongodb is type of ObjectId, so you should use ObjectId("10") when passing the parameter as below:
db.site.markets.remove({item : 'box'})
db.site.markets.remove({_id : ObjectId('10')})

Related

Find a document by a partial String value inside an array element on MongoDB from Azure

I'm trying to find all lists which the person number has '-' or '.' inside of it. I already tried this answer, but it's not working for elements inside of the array.
But when I try to find by the entire String, without the regex notation, the document is found.
Per example:
db.getCollection('list').find({"persons.number": "123456789"}) //works!
db.getCollection('list').find({"persons.number": /3/}) //not work...
db.getCollection('list').find({"persons.number": /.*3.*/}) //not work
db.getCollection('list').find({"persons.number": /.*..*/}) //not work
db.getCollection('list').find({"persons.number": /.*[-\.]+.*/}) //not work
If I try to find the document by some attribute outside of the array (an attribute from the list, per example), the /3/, /.*3.*/ and /.*[-\.]+.*/ works.
Document format:
{
"_id" : ObjectId("5af3037ee8006c4a04e84b2f"),
"id" : 1,
"persons" : [
{
"id" : 1,
"number" : "123.123.123-22"
},
{
"id" : 2,
"number" : "123.456.789-11"
}
]
}
So, what are the options?
I'm using the MongoDB from Azure. Executing the db.version() on console returns 3.2.0.
The regex .*[-\.]+.* should work,
Try this,
db.getCollection('list').find({"persons.number": /.*[-\.]+.*/})
For searching multiple patterns , i.e an OR of patterns the regex format is little different.
(pattern1)|(pattern2)
Tried the below mongo query on my local running 3.4.6 , but it should work on 3.2.x as well
db.list.aggregate([{"$unwind":{"path":"$persons"}},{"$project":{"_id":1,"persons.number":1}},{"$match":{"persons.number":{"$regex":/.*(\.)|(\-).*/}}},{"$group":{_id:"$_id"}}])

Finding an object ID embedded in an array [duplicate]

I've found this question answered for C# and Perl, but not in the native interface. I thought this would work:
db.theColl.find( { _id: ObjectId("4ecbe7f9e8c1c9092c000027") } )
The query returned no results. I found the 4ecbe7f9e8c1c9092c000027 by doing db.theColl.find() and grabbing an ObjectId. There are several thousand objects in that collection.
I've read all the pages that I could find on the mongodb.org website and didn't find it. Is this just a strange thing to do? It seems pretty normal to me.
Not strange at all, people do this all the time. Make sure the collection name is correct (case matters) and that the ObjectId is exact.
Documentation is here
> db.test.insert({x: 1})
> db.test.find() // no criteria
{ "_id" : ObjectId("4ecc05e55dd98a436ddcc47c"), "x" : 1 }
> db.test.find({"_id" : ObjectId("4ecc05e55dd98a436ddcc47c")}) // explicit
{ "_id" : ObjectId("4ecc05e55dd98a436ddcc47c"), "x" : 1 }
> db.test.find(ObjectId("4ecc05e55dd98a436ddcc47c")) // shortcut
{ "_id" : ObjectId("4ecc05e55dd98a436ddcc47c"), "x" : 1 }
If you're using Node.js:
var ObjectId = require('mongodb').ObjectId;
var id = req.params.gonderi_id;
var o_id = new ObjectId(id);
db.test.find({_id:o_id})
Edit: corrected to new ObjectId(id), not new ObjectID(id)
Even easier, especially with tab completion:
db.test.find(ObjectId('4ecc05e55dd98a436ddcc47c'))
Edit: also works with the findOne command for prettier output.
You Have missed to insert Double Quotes.
The Exact Query is
db.theColl.find( { "_id": ObjectId("4ecbe7f9e8c1c9092c000027") } )
If you are working on the mongo shell, Please refer this : Answer from Tyler Brock
I wrote the answer if you are using mongodb using node.js
You don't need to convert the id into an ObjectId. Just use :
db.collection.findById('4ecbe7f9e8c1c9092c000027');
this collection method will automatically convert id into ObjectId.
On the other hand :
db.collection.findOne({"_id":'4ecbe7f9e8c1c9092c000027'}) doesn't work as expected. You've manually convert id into ObjectId.
That can be done like this :
let id = '58c85d1b7932a14c7a0a320d';
let o_id = new ObjectId(id); // id as a string is passed
db.collection.findOne({"_id":o_id});
I think you better write something like this:
db.getCollection('Blog').find({"_id":ObjectId("58f6724e97990e9de4f17c23")})
Once you opened the mongo CLI, connected and authorized on the right database.
The following example shows how to find the document with the _id=568c28fffc4be30d44d0398e from a collection called “products”:
db.products.find({"_id": ObjectId("568c28fffc4be30d44d0398e")})
I just had this issue and was doing exactly as was documented and it still was not working.
Look at your error message and make sure you do not have any special characters copied in. I was getting the error
SyntaxError: illegal character #(shell):1:43
When I went to character 43 it was just the start of my object ID, after the open quotes, exactly as I pasted it in. I put my cursor there and hit backspace nothing appeared to happen when it should have removed the open quote. I hit backspace again and it removed the open quote, then I put the quote back in and executed the query and it worked, despite looking exactly the same.
I was doing development in WebMatrix and copied the object id from the console. Whenever you copy from the console in WebMatrix you're likely to pick up some invisible characters that will cause errors.
In MongoDB Stitch functions it can be done using BSON like below:
Use the ObjectId helper in the BSON utility package for this purpose like in the follwing example:
var id = "5bb9e9f84186b222c8901149";
BSON.ObjectId(id);
For Pythonists:
import pymongo
from bson.objectid import ObjectId
...
for row in collectionName.find(
{"_id" : ObjectId("63ae807ec4270c7a0b0f2c4f")}):
print(row)
To use Objectid method you don't need to import it. It is already on the mongodb object.
var ObjectId = new db.ObjectId('58c85d1b7932a14c7a0a320d');
db.yourCollection.findOne({ _id: ObjectId }, function (err, info) {
console.log(info)
});
Simply do:
db.getCollection('test').find('4ecbe7f9e8c1c9092c000027');

Storing a query in Mongo

This is the case: A webshop in which I want to configure which items should be listed in the sjop based on a set of parameters.
I want this to be configurable, because that allows me to experiment with different parameters also change their values easily.
I have a Product collection that I want to query based on multiple parameters.
A couple of these are found here:
within product:
"delivery" : {
"maximum_delivery_days" : 30,
"average_delivery_days" : 10,
"source" : 1,
"filling_rate" : 85,
"stock" : 0
}
but also other parameters exist.
An example of such query to decide whether or not to include a product could be:
"$or" : [
{
"delivery.stock" : 1
},
{
"$or" : [
{
"$and" : [
{
"delivery.maximum_delivery_days" : {
"$lt" : 60
}
},
{
"delivery.filling_rate" : {
"$gt" : 90
}
}
]
},
{
"$and" : [
{
"delivery.maximum_delivery_days" : {
"$lt" : 40
}
},
{
"delivery.filling_rate" : {
"$gt" : 80
}
}
]
},
{
"$and" : [
{
"delivery.delivery_days" : {
"$lt" : 25
}
},
{
"delivery.filling_rate" : {
"$gt" : 70
}
}
]
}
]
}
]
Now to make this configurable, I need to be able to handle boolean logic, parameters and values.
So, I got the idea, since such query itself is JSON, to store it in Mongo and have my Java app retrieve it.
Next thing is using it in the filter (e.g. find, or whatever) and work on the corresponding selection of products.
The advantage of this approach is that I can actually analyse the data and the effectiveness of the query outside of my program.
I would store it by name in the database. E.g.
{
"name": "query1",
"query": { the thing printed above starting with "$or"... }
}
using:
db.queries.insert({
"name" : "query1",
"query": { the thing printed above starting with "$or"... }
})
Which results in:
2016-03-27T14:43:37.265+0200 E QUERY Error: field names cannot start with $ [$or]
at Error (<anonymous>)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:161:19)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:165:18)
at insert (src/mongo/shell/bulk_api.js:646:20)
at DBCollection.insert (src/mongo/shell/collection.js:243:18)
at (shell):1:12 at src/mongo/shell/collection.js:161
But I CAN STORE it using Robomongo, but not always. Obviously I am doing something wrong. But I have NO IDEA what it is.
If it fails, and I create a brand new collection and try again, it succeeds. Weird stuff that goes beyond what I can comprehend.
But when I try updating values in the "query", changes are not going through. Never. Not even sometimes.
I can however create a new object and discard the previous one. So, the workaround is there.
db.queries.update(
{"name": "query1"},
{"$set": {
... update goes here ...
}
}
)
doing this results in:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 52,
"errmsg" : "The dollar ($) prefixed field '$or' in 'action.$or' is not valid for storage."
}
})
seems pretty close to the other message above.
Needles to say, I am pretty clueless about what is going on here, so I hope some of the wizzards here are able to shed some light on the matter
I think the error message contains the important info you need to consider:
QUERY Error: field names cannot start with $
Since you are trying to store a query (or part of one) in a document, you'll end up with attribute names that contain mongo operator keywords (such as $or, $ne, $gt). The mongo documentation actually references this exact scenario - emphasis added
Field names cannot contain dots (i.e. .) or null characters, and they must not start with a dollar sign (i.e. $)...
I wouldn't trust 3rd party applications such as Robomongo in these instances. I suggest debugging/testing this issue directly in the mongo shell.
My suggestion would be to store an escaped version of the query in your document as to not interfere with reserved operator keywords. You can use the available JSON.stringify(my_obj); to encode your partial query into a string and then parse/decode it when you choose to retrieve it later on: JSON.parse(escaped_query_string_from_db)
Your approach of storing the query as a JSON object in MongoDB is not viable.
You could potentially store your query logic and fields in MongoDB, but you have to have an external app build the query with the proper MongoDB syntax.
MongoDB queries contain operators, and some of those have special characters in them.
There are rules for mongoDB filed names. These rules do not allow for special characters.
Look here: https://docs.mongodb.org/manual/reference/limits/#Restrictions-on-Field-Names
The probable reason you can sometimes successfully create the doc using Robomongo is because Robomongo is transforming your query into a string and properly escaping the special characters as it sends it to MongoDB.
This also explains why your attempt to update them never works. You tried to create a document, but instead created something that is a string object, so your update conditions are probably not retrieving any docs.
I see two problems with your approach.
In following query
db.queries.insert({
"name" : "query1",
"query": { the thing printed above starting with "$or"... }
})
a valid JSON expects key, value pair. here in "query" you are storing an object without a key. You have two options. either store query as text or create another key inside curly braces.
Second problem is, you are storing query values without wrapping in quotes. All string values must be wrapped in quotes.
so your final document should appear as
db.queries.insert({
"name" : "query1",
"query": 'the thing printed above starting with "$or"... '
})
Now try, it should work.
Obviously my attempt to store a query in mongo the way I did was foolish as became clear from the answers from both #bigdatakid and #lix. So what I finally did was this: I altered the naming of the fields to comply to the mongo requirements.
E.g. instead of $or I used _$or etc. and instead of using a . inside the name I used a #. Both of which I am replacing in my Java code.
This way I can still easily try and test the queries outside of my program. In my Java program I just change the names and use the query. Using just 2 lines of code. It simply works now. Thanks guys for the suggestions you made.
String documentAsString = query.toJson().replaceAll("_\\$", "\\$").replaceAll("#", ".");
Object q = JSON.parse(documentAsString);

How many level can mongodb append sub-documents dynamicaly?

It seems that i can go further than one subdocument if i want to add it dynamicaly, here is the code:
db.users.update({"pup.cmn.id":id}, {"$addToSet":{"pup.cmn":{"abus":email}}})
this give error:
OperationFailure: can't append to array using string field name: cmn
then, if i add positional element i get this:
db.users.update({"pup.cmn.id":id}, {"$addToSet":{"pup.$.cmn":{"abus":email}}})
"cmn" :
[
{
"fto" : ObjectId("5190e8a53a5f3a0c102af045")
"id" : "14.05.2013 12:29:53"
},
{
"abus" : "u...#example.com"
}
]
so as you can see, it will add it in the same level, and i dont want that, because the application will get errors.
It seems that Mongodb for the time of writing (2.4.x) have not this feature, there is a ticket:
https://jira.mongodb.org/browse/SERVER-831

MongoDB: Doing $inc on multiple keys

I need help incrementing value of all keys in participants without having to know name of the keys inside of it.
> db.conversations.findOne()
{
"_id" : ObjectId("4faf74b238ba278704000000"),
"participants" : {
"4f81eab338ba27c011000001" : NumberLong(2),
"4f78497938ba27bf11000002" : NumberLong(2)
}
}
I've tried with something like
$mongodb->conversations->update(array('_id' => new \MongoId($objectId)), array('$inc' => array('participants' => 1)));
to no avail...
You need to redesign your schema. It is never a good idea to have "random key names". Even though MongoDB is schemaless, it still means you need to have defined key names. You should change your schema to:
{
"_id" : ObjectId("4faf74b238ba278704000000"),
"participants" : [
{ _id: "4f81eab338ba27c011000001", count: NumberLong(2) },
{ _id: "4f78497938ba27bf11000002", count: NumberLong(2) }
]
}
Sadly, even with that, you can't update all embedded counts in one command. There is currently an open feature request for that: https://jira.mongodb.org/browse/SERVER-1243
In order to still update everything, you should:
query the document
update all the counts on the client side
store the document again
In order to prevent race conditions with that, have a look at "Compare and Swap" and following paragraphs.
It is not possible to update all nested elements in one single move in current version of MongoDB. So I can advice to use "foreach {}".
Read realted topic: How to Update Multiple Array Elements in mongodb
I hope this feature will be implemented in next version.