I have thousands of items in my gameItem collection with the following as example.
{
"weapon name 1":{price:01},
"weapon name 2":{price:100}
}
and I run a query like so in shell
db.gameItems.find({"weapon name 1":{$exists:1}})
nothing returns but it works when my keys don't have spaces...
First questions: Is there a way to search key values with spaces?
Second question: Should I change my data model to be like so?:
{
weapon:{name: "weapon name 1", price:01}
weapon:{name: "weapon name 2", price:100}
}
And then add an index to the weapon name field? Does this increase search performance with only 2 fields in each weapon document?
Thanks
Edit:
Apologies, it appears the db collection gameItems actually looks like this...
{
last_updated:"2016-04-01",
items:{
"weapon name 1":{price:01},
"weapon name 2":{price:100}
}
}
so how would I search for them inside the item document?
use single quotations where key have space.
run below .
db.gameItems.find({'weapon name 1':{$exists:1}})
Related
How to index nested objects in Pymongo so that I can perform full text search. For example I've the collection object like this...
{
"_id":"ObjectId(" "5e8b0fa1c869790699efdb2d" ")",
"xmlfileid": "334355343343223567",
"threads":{
"threads_participants":{
"participant":[
{
"#reference": rits_dbx_1
},
{
"#reference": rits_dbx_2
}
]
},
"thread":{
"namedAnchor":"{' ': 'NORP', 'Ho': 'PERSON', 'Lets': 'PERSON', 'Boris Johnson': 'PERSON', 'Britain': 'GPE'}",
"selectedText":{
"fragment":[
{
"#class":"next_steps",
"#text":"rits_dbx_1 said hello this is a good site."
},
{
"#class":"other",
"#text":"rits_dbx_1 said ho ho."
},
{
"#class":"other",
"#text":"rits_dbx_1 said lets put some meaningful stuff here."
},
]
}
}
}
}
I've placed search box in my website and when user types the #text in search box I want to display the #text and class and the xmlfileid
So far I've created index using below command. And I don't know it's the right way to get the result and also please help with query too.
db.xml_collection.createIndex({"threads.thread.selectedText.fragment": "text"})
In my python code I've this but that prints nothing
result = collection.find({"$text": {"$search": "ho ho"}})
Your index is wrong.
MongoDB provides text indexes to support text search queries on string content. text indexes can include any field whose value is a string or an array of string elements.
https://docs.mongodb.com/manual/core/index-text/
If you want to index only #text field, change your index to this:
db.xml_collection.createIndex({"threads.thread.selectedText.fragment.#text": "text"})
Also, you may create Wildcard text index and MongoDB will index all key:value pairs (where value is string / array of string)
db.xml_collection.createIndex({"$**": "text"})
Note: You need to drop any previous text indexes for this collection
I am a newbie in mongodb, my second day of playing with this, and I would like to get some help for my question below!
I would like to duplicate or copy a set of objects instances that match the specific field, and then copy them and save them with new ObjectIds.
Example
db.getCollection('food').find( { food_type: "fruit" } )
The query above with show me 8 documents with 8 fields each: food_type, name, description, color, origin, import_price, export_price, margin.
I have 8 types of fruits, and the query
totalFoodTypes = db.getCollection('food').count( { food_type: "fruit" } )
will return 8. I would like to copy all these 8 documents into another brand new 8 documents with new ObjectIds and food_type field value changed to Vegetable. Is there an easy way for doing that?
My current best thinking is to store the result from
db.getCollection('food').find( { food_type: "fruit" } )
and then loop totalFoodTypes documents and insert them one by one with Java.
Would be really appreciated if mongodb has some shortcut for doing this.
I've read the MongoDB documentation on getting the indexes within a collection, and have also searched SO and Google for my question. I want to get the actual indexed values.
Or maybe my understanding of how MongoDB indexes is incorrect. If I've been indexing a field called text that contains paragraphs, am I right in thinking that what gets indexed is each word in the paragraph?
Either case I want to retrieve the values that were indexed, which db.collection.getIndexes() doesn't seem to be returning.
Well yes and no, in summary.
Indexes work on the "values" of the fields they are supplied to index, and are much like a "card index" in that there is a point of reference to look at to find the location of something that matches that term.
What "you" seem to be asking about here is "text indexes". This is a special index format in MongoDB and other databases as well that looks at the "text" content of a field and breaks down every "word" in that content into a value in that "index".
Typically we do:
db.collection.createIndex({ "text": "text" })
Where the "field name" here is "text" as you asked, but more importantly the type of index here is "text".
This allows you to then insert data like this:
db.collection.insert({ "text": "The quick brown fox jumped over the lazy dog" })
And then search like this, using the $text operator:
db.collection.find({ "$text": { "$search": "brown fox" } })
Which will return and "rank" in order the terms you gave in your query depending how they matched the given "text" of your field in the index on your collection.
Note that a "text" index and it's query does not interact on a specific field. But the index itself can be made over multiple fields. The query and the constraints on the "index" itself are that there can "only be one" text index present on any given collection otherwise errors will occur.
As per mongodb's docs:
"db.collection.getIndexes() returns an array of documents that hold index information for the collection. Index information includes the keys and options used to create the index. For information on the keys and index options, see db.collection.createIndex()."
You first have to create the index on the collection, using the createIndex() method:
db.records.createIndex( { userid: 1 } )
Queries on the userid field are supported by the index:
Example:
db.records.find( { userid: 2 } )
db.records.find( { userid: { $gt: 10 } } )
Indexes help you avoid scanning the whole document. They basically are references or pointers to specific parts of your collection.
The docs explain it better:
http://docs.mongodb.org/manual/tutorial/create-an-index/
I am working with a set of documents like this:
{
name : "BCC 204",
//etc
}
I have a list of names that I want to map to their DB entries.
For example:
var names = [ "BCC 204", "STEW 101", "SMTH 123" ]
and I want to make a query like this
db.labs.find( { name : { $in: names } } );
But the $in operator does not ensure that each item in the names array matches a result in the db.
(More info, names are unique)
You can't do this in the query. $in will check that a document matches at least one entry in the array given, but it's not going to consider the entire result set. This is a concern you'll need to manage in your application. Given a list of inputs, you will need to retrieve your results then check that given_names - results.map(:name) is empty.
To put it more simply, queries match documents, which compose a result set - they don't match a result set.
I want rename to rename my dict key in mongodb.
normally it works like that db.update({'_id':id},{$rename:{'oldfieldname':newfieldname}})
My document structure looks like that
{
'data':'.....',
'field':{'1':{'data':....},'2':{'data'...}},
'more_data':'....',
}
if i want to set
a new field in field 1 i do db.update({'_id':id},{$set:{'field.0.1.name':'peter'}})
for field two it is 'field'.1.2.name'
i thought with the rename it should be similar but it isn't ... (like $rename:{'field'.0.1': 2}
Here's a flexible method for renaming keys in a database
Given a document structure like this...
{
"_id": ObjectId("4ee5e9079b14f74ef14ddd2f"),
"code": "130.4",
"description": "4'' Socket Plug",
"technicalData": {
"Drawing No": "50",
"length": "200mm",
"diameter: "20mm"
},
}
I want to loop through all documents and rename technicalData["Drawing No"] to technicalData["Drawing Number"]
Run the following javascript in the execute panel in (the excellent) RockMongo
function remap(x){
dNo = x.technicalData["Drawing No"];
db.products.update({"_id":x._id}, {
$set: {"technicalData.Drawing Number" : dNo},
$unset: {"technicalData.Drawing No":1}
});
}
db.products.find({"technicalData.Drawing No":{$ne:null}}).forEach(remap);
The code will also run in a mongo shell
Your question is unclear but it seems you'd like to rename a field name within an array.
The short answer is you can't. As stated in the docs, $rename doesn't expand arrays to find a matching name. It only works on top level fields.
What you can do to simulate rename is by copying the field and its data to the new name, and then deleting the original field. You might also need a way to account for potentially concurrent writes if you have a lot of writes to that object/field.