0

With SQL we can do the following :

select * from x where concat(x.y ," ",x.z) like "%find m%"

when x.y = "find" and x.z = "me".

How do I do the same thing with MongoDB, When I use a JSON structure similar to this:

{
  data:
  [
     {
         id:1,
         value : "find"
     },
      {
         id:2,
         value : "me"
     }
  ]
}
chridam
  • 100,957
  • 23
  • 236
  • 235
user2288183
  • 121
  • 2
  • 11
  • 1
    No field corresponding to "x.y" or "x.z" and a completely invalid structure. Bit tired on "in SQL we can do.." questions. Especially when there is no logical structure as in this example. Ask a better question. – Neil Lunn Nov 06 '14 at 14:08
  • @NeilLunn Please explain what don't you understand and I can explain myself better. It's not a good reason to rank the question down only because you "tired" of certain type of questions . I'm sure that more than one person is struggling with this type of problem. – user2288183 Nov 06 '14 at 14:18
  • Well geez. After you edit the structure is at least valid. But all I see here is a common path to "data.value". Hardly the "x.y" "x.z" you describe. Don't make it my problem. It's your job to explain yourself to people who you want help from. Otherwise you wouldn't need to ask if you knew the answer. BTW. The person who takes the time to prompt you to "do better" is usually not the person who "ranked you down". So get off your high horse. You asked a bad question. Someone downvoted you for that. Do better. – Neil Lunn Nov 06 '14 at 14:25
  • http://docs.mongodb.org/manual/reference/operator/query/regex/ – Disposer Nov 06 '14 at 16:00

1 Answers1

1

The comparison to SQL here is not valid since no relational database has the same concept of embedded arrays that MongoDB has, and is provided in your example. You can only "concat" between "fields in a row" of a table. Basically not the same thing.

You can do this with the JavaScript evaluation of $where, which is not optimal, but it's a start. And you can add some extra "smarts" to the match as well with caution:

db.collection.find({
    "$or": [
        { "data.value": /^f/ },
        { "data.value": /^m/ }
    ],
    "$where": function() {
        var items = [];
        this.data.forEach(function(item) {
            items.push(item.value);
        });
        var myString = items.join(" ");

        if ( myString.match(/find m/) != null )
            return 1;
    }
})

So there you go. We optimized this a bit by taking the first characters from your "test string" in each word and compared the tokens to each element of the array in the document.

The next part "concatenates" the array elements into a string and then does a "regex" comparison ( same as "like" ) on the concatenated result to see if it matches. Where it does then the document is considered a match and returned.

Not optimal, but these are the options available to MongoDB on a structure like this. Perhaps the structure should be different. But you don't specify why you want this so we can't advise a better solution to what you want to achieve.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317