How can I do a find and replace all in MongoDB? - mongodb

For example suppose I insert data as follows
doc1 = [{url: 'http://domain.com/pic1.jpg'}, {url: 'http://domain.com/pic2.jpg'}]
doc2 = [{url: 'http://domain.com/pic3.jpg'}, {url: 'http://domain.com/pic4.jpg'}]
db.picture.insert(doc1)
db.picture.insert(doc2)
How could I replace all 'http' with 'https'?

MongoDB does not have in-built support for search and replace of a portion of a string. You could write a program in your favourite scripting language to do this.
You can use regular expression searching to get back all the URLs that start with "http:":
db.picture.find({url: /^http:/})
You could do that in your program to get the data, then modify it in your program, and update or replace the documents with the new values.

Related

MongoDB findOneAndReplace log if added as new document or replaced

I'm using mongo's findOneAndReplace() with upsert = true and returnNewDocument = true
as basically a way to not insert duplicate. But I want to get the _id of the new inserted document (or the old existing document) to be passed to a background processing task.
BUT I also want to log if the document was Added-As-New or if a Replacement took place.
I can't see any way to use findOneAndReplace() with these parameters and answer that question.
The only think I can think of is to find, and insert in two different requests which seems a bit counter-productive.
ps. I'm actually using pymongo's find_one_and_replace() but it seems identical to the JS mongo function.
EDIT: edited for clarification.
Is it not possible to use replace_one function ? In java I am able to use repalceOne which returns UpdateResult. That has method for finding if documented updated or not. I see repalce_one in pymongo and it should behave same. Here is doc PyMongo Doc Look for replace_one
The way I'm going to implement it for now (in python):
import pymongo
def find_one_and_replace_log(collection, find_query,
document_data,
log={}):
''' behaves like find_one_or_replace(upsert=True,
return_document=pymongo.ReturnDocument.AFTER)
'''
is_new = False
document = collection.find_one(find_query)
if not document:
# document didn't exist
# log as NEW
is_new = True
new_or_replaced_document = collection.find_one_and_replace(
find_query,
document_data,
upsert=True,
return_document=pymongo.ReturnDocument.AFTER
)
log['new_document'] = is_new
return new_or_replaced_document

how to find partial search in Mongodb?

How to find partial search?
Now Im trying to find
db.content.find({$text: {$search: "Customer london"}})
It finds all records matching customer, and all records matching london.
If I am searching for a part of a word for example lond or custom
db.content.find({$text: {$search: "lond"}})
It returns an empty result. How can I modify the query to get the same result like when I am searching for london?
You can use regex to get around with it (https://docs.mongodb.com/manual/reference/operator/query/regex/). However, it will work for following :
if you have word Cooking, following queries may give you result
cooking(exact matching)
coo(part of the word)
cooked(The word containing the english root of the document word, where cook is the root word from which cooking or cooked are derived)
If you would like to go one step further and get a result document containing cooking when you type vooking (missplled V instead of C), go for elasticsearch.
Elasticsearch is easy to setup, has extremely powerful edge-ngram analyzer which converts each words into smaller weightage words. Hence when you misspell, you will still get a document based on score elasticsearch gives to that document.
You can read about it here : https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-edgengram-tokenizer.html
it will always return the empty array for partial words like when you are searching for lond to get this type of text london..
Because it take full words and search same as that they are ..
Not achive same results like :-
LO LON LOND LONDO LONDON
Here you may get help from ELASTIC-SEARCH . It is quite good for full text search when implement with mongoDB.
Refrence : ElasticSearch
Thanks
The find all is to an Array
clientDB.collection('details').find({}).toArray().then((docs) =>
I now used the str.StartWith in a for loop to pick out my record.
if (docs[i].name.startsWith('U', 0)) {
return console.log(docs[i].name);
} else {
console.log('Record not found!!!')
};
This may not be efficient, but it works for now

jessenger mongodb case insensitive query search

I have 1 issue with mongodb query search with exact values. i want to get collections irrespective of case sensitive. for this i found some querys like below. its working fine.
db.applications.find({"blocks.HOSPITAL_INFO.data.name": new RegExp('^VIKRAM$', 'i')});
in laravel i am using jessengers. . above query i can write as raw query in laravel.
but my issue is when ever i am using $In:{'a','b'} like this how can i write regex for this. FYI 'a','b' are dynamic array values. so how can i write regex for these array values?
The query in MongoDB would be something like this:
db.applications.find({"blocks.HOSPITAL_INFO.data.name":
{$in:[new RegExp('^a$', 'i'),new RegExp('^b$', 'i')]}});
OR, alternatively:
db.applications.find({"blocks.HOSPITAL_INFO.data.name":
{$in:[/^a$/i,/^b$/i]}});
...where a & b are your dynamic variables.
I'm not very familiar with Laravel, but I'm guessing it would look something like this:
$applications = Application::whereIn('blocks.HOSPITAL_INFO.data.name',
[new MongoRegex('^a$/i'), new MongoRegex('^b$/i')])->get();

Elasticsearch mongodb river script in index doesn't work

I'm trying to change few fields strings using javascript.
For example take only the last part of the URL taken from mongo through the river so in elasticsearch I'll have only the end of it.
When creating the index (using curl) I added under "options" the following script:
"script": "ctx.document.shorturl = ctx.document.url.substr(-4);delete ctx.document.url;
I tried some manipulations such as adding \"...\" or use ctx['doc']['url'] and others but nothing seems to work.
I always get only url field with the full url (shorturl is not created at all).
Can anyone suggest what is the right syntax to make it work?
Another thing I need to do is combine to fields - lat & long, to one "location" field in order to use it in Kibana, can anyone suggest the right script for that? (create new field called "location" which contain both field "lat" & "long" with comma between them).
Thanks.
You did substring(-4), hence it will return the whole string. You should use substring(4) instead:
ctx.document.shorturl = ctx.document.url.substr(4);delete ctx.document.url;

Mongoid, find object by searching by part of the Id?

I want to be able to search for my objects by searching for the last 4 characters of the id. How can I do that?
Book.where(_id: params[:q])
Where the param would be something like a3f4, and in this case the actual id for the object that I want to be found would be:
bc313c1f5053b66121a8a3f4
Notice the last for characters are what we searched for. How can I search for just "part" of my objects id? instead of having my user search manually by typing in the entire id?
I found in MongoDB's help docs, that I can provide a regex:
db.x.find({someId : {$regex : "123\\[456\\]"}}) // use "\\" to escape
Is there a way for me to search using the regular mongo ruby driver and not using Mongoid?
Usually, in Mongoid you can search with a regexp like you normally would with a string in your call to where() ie:
Book.where(:title => /^Alice/) # returns all books with titles starting with 'Alice'
However this doesn't work in your case, because the _id field is not stored as a string, but as an ObjectID. However, you could add (and index) a field on your models which could provide this functionality for you, which you can populate in an after_create callback.
<shameless_plug>
Alternatively, if you're just looking for a shorter solution to the default Mongoid IDs, I could suggest something like mongoid_token which makes it pretty easy to add shorter tokens/ids to your Mongoid documents.
</shameless_plug>