1

$ne in momgodb using java not giving proper result. Am i missing something? My database is as below. enter image description here

Which contains value where mac_address = "-".

My code for retrieving records where mac_address != "-" is as,

BasicDBObject whereQuery = new BasicDBObject("mac_address", new BasicDBObject("$ne", "-"));
DBCursor cursor = node_info.find(whereQuery);

It's returning all the records. What can be probably wrong.?

Update i converted your suggested query as follow. what's wrong in this?

    BasicDBObject unwind= new BasicDBObject("$unwind","$nodes");
    BasicDBObject mac = new BasicDBObject("mac_address", "$nodes.mac_address");
    BasicDBObject projection= new BasicDBObject("$project",mac);
    BasicDBObject match = new BasicDBObject("$match", new     BasicDBObject("mac_address",notEqual));
   node_info.aggregate(unwind, projection, match);

Sorry i am not much familiar with mongodb query.

Hitesh Vaghani
  • 1,342
  • 12
  • 31

1 Answers1

3

As far as I can see, the nodes is a nested array and you're not property querying it.

In order to filter by a property of a nested array, you have to use the $elemMatch operator. By documentation:

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

So, this query should be working:

db.node_info.find({ 
  nodes : { 
    $elemMatch : { 
      mac_address : { $ne : "-" } 
    } 
  }
})

This query has to be translated to a BasicDBObject with which you would work in Java. It should be something like:

BasicDBObject query = new BasicDBObject();
BasicDBObject notEqual = new BasicDBObject("$ne", "-");
BasicDBObject macCriteria = new BasicDBObject("mac_address", notEqual);
BasicDBObject elemMatch = new BasicDBObject("$elemMatch, macCriteria);
query.put("nodes", elemMatch);

Update:

The problem with the solution above is that the query will actually return all the node_info documents that match the provided criteria and will include the nested array documents that do not match the criteria.

In order to return only the nested array documents, for which mac_accress != "-", you have to do aggregation. The aggregation query in Mongo would be:

db.node_info.aggregate([
    { $unwind : "$nodes" },
    { $project : { mac : "$nodes.mac_address" } },
    { $match : { mac : { $ne : "-" } } }
])

This will return only the documents, for which the mac_address is not "-". Of course, you select other fields of the documents to be included in the result. In order to do so, you have to enumerate the desired fields in the $project pipeline stage .

Also, this query has to be translated in BasicDBObject object(s), but this can be done similarly to above.

Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
  • 2
    @HiteshVaghani As an additional info: You were querying for `mac_address` fields in the root of each document. Since your documents don't seem to have that field, it evaluates to `null`, which *is* not equal `-`, hence all documents are returned. – Markus W Mahlberg Apr 09 '15 at 07:41
  • I tried this query { "nodes" : { "$elemMatch" : { "mac_address" : { "$ne" : "-"}}}}. This is giving the same result as before. – Hitesh Vaghani Apr 09 '15 at 08:04
  • @HiteshVaghani, that's actually what is supposed to happen, because we're querying documents from `node_info` that match some criteria. We've never specified that we want *some* of the nested documents in the array, we just specified that we want all the `node_info` document, in which nested array there's some object that meets some criteria. – Konstantin Yovkov Apr 09 '15 at 08:18
  • @kocko Exactly i got the problem. Thanks. Tried to solve it but hadn't succeeded. – Hitesh Vaghani Apr 09 '15 at 08:32
  • @kocko please checkout my update. – Hitesh Vaghani Apr 09 '15 at 08:59
  • @kocko: please look at this question. Same problem arise again.http://stackoverflow.com/questions/29600055/mongodb-remove-query-using-java-not-working – Hitesh Vaghani Apr 13 '15 at 07:51