0

Am using mongo to store my documents. And one of them looks like below.

Name:
  first: joe
  last: blo
address:
  city: Paris
  state: London
relatives:
  first order:
      aunt: ashley
      uncle: tom
  second order
      aunt: roma
      uncle: robin

I would like to be able to perform a query which would give me documents that match 'aunt':'roma'. Am using mongo java api to access it

From what I have understood and read the following query should work, but it doesnt

 DBObject winner = new BasicDBObject("$match", new BasicDBObject("aunt", "roma") );
 System.out.println("count "+coll.aggregate(winner).getCommandResult());

Can anyone help me understand and explain why this is failing?

Thanks K

rdonatoiop
  • 1,185
  • 1
  • 14
  • 28
Karthik Balasubramanian
  • 1,127
  • 4
  • 13
  • 36
  • 2
    why is it so hard for people to post normal JSON? – Salvador Dali Nov 09 '13 at 01:23
  • 1
    There is no reason to use aggregation here. When you want to find documents by equality, you can use a normal find-query. – Philipp Nov 09 '13 at 01:26
  • 1
    Your mistake in this case was that you search for the field `aunt:roma`at the root-level of the document. You won't find it there. The only fields you have on that level are `Name`, `address` and `relatives`. What you actually want to search for is the field `"relatives.second order.aunt":"roma"` – Philipp Nov 09 '13 at 01:27
  • I would like to move away from having to know that structure "relatives.second.order.aunt". Hence the need for a match clause. – Karthik Balasubramanian Nov 09 '13 at 01:54
  • You want a feature that is not supported in MongoDB. You'd need to change the schema to support your general query needs. – WiredPrairie Nov 09 '13 at 02:47

1 Answers1

1

My suggestion is that, for better understanding, you practice a bit using the MongoDb javascript console to test your queries first against your database collections, then later you get to write them directly for the driver you are using (Java in your case). An example:

To match a document described like this

{
    name: {
        first: "joe",
        last: "blo"
    } ,
    address: {
        city: "Paris",
        state: "London"
    },
    relatives: {
        first_order: {
            aunt: "ashley",
            uncle: "tom"
        },
        second_order: {
            aunt: "roma",
            uncle: "robin"
        }
    }
}

you would build a query like this

db.my_collection.find({"relatives.second_order.aunt": "roma"})

To have the document inserted into a collection called my_collection, it´s simple as

db.my_collection.insert(
{
    name: {
        first: "joe",
        last: "blo"
    } ,
    address: {
        city: "Paris",
        state: "London"
    },
    relatives: {
        first_order: {
            aunt: "ashley",
            uncle: "tom"
        },
        second_order: {
            aunt: "roma",
            uncle: "robin"
        }
    }
})

Some references you may read to get your queries properly written to Java API: http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/

And the docs for playing around with the MongoDb console, in this case with querying subdocuments: http://docs.mongodb.org/manual/reference/method/db.collection.find/#query-subdocuments

Hope it helps.

rdonatoiop
  • 1,185
  • 1
  • 14
  • 28
  • Thanks for the info, but as I have said before, I would like to not know the structure relatives.second_order.aunt to be able to search for aunts. I dont want to rely on the document structure because am afraid if they change, then I would have to make changes on my end to accommodate that. I know for sure the key "Aunt" is going to be present in the document, why cant I just query for that key? – Karthik Balasubramanian Nov 09 '13 at 02:29
  • You mean you have "Aunt" to be anywhere in the document (even arbitrarily nested)? I really don't know how you could achieve that without having some basic knowledge of the doc structure. – rdonatoiop Nov 09 '13 at 02:42
  • Yes, that is correct. I know for any given person, there would be a key called 'Aunt' but I dont want to rely on the structure. In some sense I mean to perform a lucene sort of search on the document to get to the key am interested in – Karthik Balasubramanian Nov 09 '13 at 02:59
  • Well, just crossed my mind that the problem you´re facing could be solved with an ER database, in which you would have a table "aunt" along with the rest of the structure. You could then retrieve the entities having a relationship with 'aunt' in any sort. Of course that is just a ponderation, not a practical solution since it would require an entire redesign. But, indeed, the problem looks to me less of a NO-SQL one. – rdonatoiop Nov 09 '13 at 03:23
  • Let me explain the problem so as to establish the context. I have a bunch of yaml files which serves as my data. These are thrid party files and I have no control over their structure. I need to store them and be able to query them and do analysis on the data. For example I need to know how many people have third order aunts whose name is 'roma' – Karthik Balasubramanian Nov 09 '13 at 03:31