--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
Thanks for the answer. However, I think I was not clear enough on what
I need. I'll try again now that I know also a little more.
So, I have 100 nodes that are going through data with some strings in
it. These strings need to be mapped to unique int, however, the
problem is that there are 100 nodes doing this concurrently.
So, here is some pseudo code in the java client in node N:
String S = read.line();
int i = MongoDB.getInt(S);
if (i == null){ // i.e. the string S was not in DB, let's insert it there
int nexti = MongoDB.getInt("Current Max Value");
i = nexti + 1;
MongoDB.setInt2S(S, i);
MongoDB.setInt2S("Current Max Value", i);
}
So, the worry is that as I have 100 nodes doing this at the same time
(and at worst case as fast as possible), so different nodes could get
same int mapped to different strings. Most of the calls should hit old
values and be just nice gets and threading and non-blocking access is
great for that.
So, if I'd now use inc or findAndModify to update the "Current Max
Value", I'd still have the risk that different nodes asking mapping
for same string, would end up with different int mapping.
So, what I was thinking is to have a function like this:
function new(id){
var max = db.map.findOne({"_id" : "Current Max Value"});
max.value++;
db.map.save(max);
db.map.save({"_id" : id, "value" : max.value});
return max.value;
}
And now, my thinking is that if I run this with eval, this will block
the DB until the function has run. And therefore I'm safely
incrementing the max value and storing the string with that value
before anybody else can ask for either one.
So, 2 questions:
- am I on right track? Or did I misunderstand what you were saying?
- how do I call this function from Java?
Thanks again!
--
HG.
Sorry, I'm just starting with MongoDB and I guess I don't see how I
could do this with $inc and findAndModify. Please bear with me. The
java API docs don't have much explanation anywhere. So maybe I don't
understand these correctly. This for instance is how I understood that
I need to simple put that either puts new value with the key or if the
key already exists, replaces the value:
public boolean put(String key, String value) {
BasicDBObject row = new BasicDBObject();
row.put("_id", key);
DBObject old = coll.findOne(row);
if (old == null){
BasicDBObject doc = new BasicDBObject();
doc.put("_id", key);
doc.put("value", value);
coll.insert(doc);
return true;
} else {
old.put("value", value);
coll.findAndModify(row, old);
return true;
}
}
Have I understod findAndModify incorrectly?
However, that is not directly what I'm looking for. From the link that
you gave, the case "Insert if Not Present" is close to what I wanted
to do. They don't use $inc nor findAndModify, but they do create a
function for that. So, Nat, can you show me example on how to do what
I want with $inc and findAndModify?
Thanks in advance!
--
HG.
I think you understood my problem. What you propose seems to be ok -
except that I need to check the gaps. But otherwise - thanks a lot!
This is how far I got myself:
1) In java, get index for string
2) if it returns null, then call this function on server:
> function saveAndGetNew(s){
... var newstr = db.map.findOne({"_id" : s});
... if (newstr == null){
... var max = db.map.findOne({"_id" : 0});
... max.CurrentMax++;
... db.map.save(max);
... db.map.save({"_id" : s, "index" : max.CurrentMax});
... return max.CurrentMax;
... } else {
... return newstr.index;
... }
... }
> db.map.save({"_id": 0, "CurrentMax" : 0})
Which seems to work:
> db.map.find()
{ "_id" : 0, "CurrentMax" : 0 }
> saveAndGetNew("String1")
1
> saveAndGetNew("String2")
2
> saveAndGetNew("String3")
3
> saveAndGetNew("String2")
2
> db.map.find()
{ "_id" : 0, "CurrentMax" : 3 }
{ "_id" : "String1", "index" : 1 }
{ "_id" : "String2", "index" : 2 }
{ "_id" : "String3", "index" : 3 }
So, now if I can call this from Java, I can try you method and this to
see which works faster. (Yes, I will cache all ID's on the client
nodes as far as I have memory there.) However, how to call that from
Java (as was my original question)? Java docs contain "eval" and
"doEval" however, the javadoc doesn't tell anything about those
commands, so I don't know what they do or how to use them (at least my
trial calls such as above from the shell, have not worked).
--
HG
Thanks! I guess my problem was that I had not saved the function to
right place. However, what is the difference with .eval and .doEval?
The API doesn't way anything about them (or even the args). Why are
you first running .doEval and then just .eval?
Ps. no need for sharding yet and if I get that big, I will need to use
something else than Mongo. I like Mongo a lot, but I've been told that
"there is no way to go to production with mongo because it is loosing
data". So as long as I have everything under my control, I'm fine with
Mongo :-)
--
HG.
what is the difference with .eval and .doEval?
The API doesn't say anything about them (or even the args). Why are
you first running .doEval and then just .eval?
I've been told that
"there is no way to go to production with mongo because it is loosing
data".
On Tue, Jan 18, 2011 at 6:51 PM, Keith Branton <ke...@branton.co.uk> wrote:
>>
>> what is the difference with .eval and .doEval?
>> The API doesn't say anything about them (or even the args). Why are
>> you first running .doEval and then just .eval?
>>
> The best documentation is well written code - always accurate and very
> up-to-date. The mongo driver is pretty well written. The difference can be
Well... yes, it works for those who write that code, I agree. However,
for the rest of us who write our own code and want to use some great
library to help there, it really doesn't make sense to start learning
your code as there is just no time for such. Therefore, the
documentation is what enables to use great libraries and products.
With IDE, you just import the API docs and go from there. But since
the API docs are completely empty, it's really hard to use and it's
much easier to move to something else that is documented and let's me
concentrate on my problem.
But thanks for the code - I understand the difference now.
>> I've been told that
>> "there is no way to go to production with mongo because it is loosing
>> data".
>
> I have not experienced this, and I fully plan to go into production using
> Mongo in the next month or so. Do you have any further details as to where
> it's loosing data? I know about the following...
Like I wrote, I've been told from our architects (I do trust them
mostly) not to trust it (no evidence). I don't question MongoDB! It
was just a side remark that I will not be allowed to use MongoDB for
more than adhoc things I'm sure. I've not experienced anything and am
not worried at all.
--
HG.