6

I want to update a collection which only contains some Id and a dictionary of objectId to objectId.

public class ME_BlaBla
{
    [BsonId]
    public ObjectId MyId;
    public Dictionary<ObjectId, ObjectId> IdsToOtherIds;
}

Im sorry if my names aren't informative, I can't share real code =.

Now, I have this query:

var filter = Builders<ME_BlaBla>.Filter.And(
            Builders<ME_BlaBla>.Filter.Eq(t => t.MyId, id),
            Builders<ME_BlaBla>.Filter.Not(Builders<ME_BlaBla>.Filter.Exists(t => t.IdsToOtherIds.Values, valueId)),
            Builders<ME_BlaBla>.Filter.Not(Builders<ME_BlaBla>.Filter.Exists(t => t.IdsToOtherIds.Keys, keyId)));

So, Im trying to filter by the MyId field but when I want to insert data to there I don't want duplication of any kind, Not in the Keys nor in the Values

The whole idea is that the updating must be atomic and check that neither of the provided ids are contained in the dictionary.

I'm still trying to understand how to use the Existsfilter here, so it might be the answer.

TIA.

EDIT

I changed the code to something like that: (still not sure its working well..cannot test it atm)

Builders<ME_BlaBla>.Filter.Not(Builders<ME_BlaBla>.Filter.ElemMatch(t => t.IdsToOtherIds, a => a.Key == keyId)),
Builders<ME_BlaBla>.Filter.Not(Builders<ME_BlaBla>.Filter.ElemMatch(t => t.IdsToOtherIds, a => a.Value == valueId)));
rene
  • 41,474
  • 78
  • 114
  • 152
Ori Refael
  • 2,888
  • 3
  • 37
  • 68
  • 1
    Something you have to share at least a brief description of the table, because I'm not very sure you're using the dictionary correctly there. This field IdsToOtherIds doesn't seem to be correct. – Maximiliano Rios Jan 19 '16 at 21:35
  • 1
    What is valueId and keyId in your code? What does it represent? You say "nor the keys neither the values" but based on the serialization this is not what you represent there. Your serialization is like this { _id: ObjectId(xxx), ObjectId(yyyy) : ObjectId(zzzz), ObjectId(yyyy1) : ObjectId(zzzz1), ... } which doesn't make too much sense. – Maximiliano Rios Jan 19 '16 at 21:44
  • i dont know how to make it simpler. imagine i have a dictionary. dictionary has Keys and Values. when i provide 2 different ids i want Id1 to not be in the dictionary Keys and id2 wont be in the dictionary Values. I can't see what is missing here. i provided the entire class that is stored on the db, what kind of table description u're missing? – Ori Refael Jan 20 '16 at 10:27
  • @Ori - There are different ways of serializing a Dictionary with the C# driver. How it gets serialized can affect what is possible when querying. If I take your class definition and attempt to insert some sample data to a collection using the current driver, I get the following error: MongoDB.Bson.BsonSerializationException : When using DictionaryRepresentation.Document key values must serialize as strings. So, like Maximiliano said, it would be useful to see what the data looks like in your database. – Peter Jan 20 '16 at 16:00

2 Answers2

2
Builders<ME_BlaBla>.Filter.Not(Builders<ME_BlaBla>.Filter.Exists(t => t.IdsToOtherIds.Values, valueId))

This part of code won't check if valueId value exists in the Values property (which is a list of elements of type ObjectId) of the field Dictionary (that's what you meant, I guess). Exists checks if the document contains certain field; you could check if document of your collection have a field "Dictionary" or "Surname".

If you need a unique value in your application, could you possibly create a singleton class somewhere which will generate next (and thus unique) value of certain sequence?

Your Dictionary probably is serialized as array of documents, so if you need to check whether document already exist in the collection, you need to use AnyIn (or some other) instead of Exists.

maciek
  • 521
  • 1
  • 4
  • 18
  • Well. it sorta the direction but still not answering my question. basically my issue is not creating or inserting unique ids. Lets assume a user has a parent, ok? user can only have 1 parent. both of them are represented by ids, different one for each. now, i have a child and a parent. i want to check that this parent is not a parent of someone else AND ALSO check that the child is not a child of some other parent. if these 2 conditions happens than i want to insert the KeyPairValue. – Ori Refael Jan 20 '16 at 18:03
  • Code you added to the question seems OK, does it work? Based on numbers of brackets I assume you added `And` filter before the code which is posted. – maciek Jan 22 '16 at 17:21
  • I cant actually test it because im on a vacation, but thats probably it. And yes, the edit is replacing the last 2 lines of code in the original post – Ori Refael Jan 22 '16 at 19:19
0

You can look nested list existance with your criteria like that,

https://docs.mongodb.org/manual/core/read-operations-introduction/

in your state you can use your dictionaries as 2 union criteria like that,

https://docs.mongodb.org/manual/reference/operator/query/elemMatch/

cheers!

Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35
  • But, isnt that what i wrote in the my edit? Or im missing smth here – Ori Refael Jan 26 '16 at 08:21
  • i think in your case you should iterate your first dictionary or maybe this link is a alternative http://stackoverflow.com/questions/20662691/how-to-search-through-a-mongodb-collection-for-dictionary-keys-nested-in-array – Hamit YILDIRIM Jan 26 '16 at 08:41
  • I only have 1 dictionary to iterate on..i still dont see how the dictionary values are handled this way. Also, i would like very much if i can be directed using the c# mongodb driver because i dont really know the Mongo systax itself – Ori Refael Jan 26 '16 at 10:39
  • control its existance before insert like this http://stackoverflow.com/questions/10467825/how-to-query-a-sub-document-collection-using-mongodb-and-c-sharp-driver – Hamit YILDIRIM Jan 26 '16 at 13:43