frankcheong
frankcheong

Reputation: 55

Meteor.find multiple values in an array

I am using auto schema to define an array field. I need to find documents where multiple specific values are contained in that array. I know I can use the $in: operator while $in: can only match either one of the value in the first array against the second array while I would need to match any record that have all value in the first array. How I can achieve this?

Schema Definition

Demands = new Mongo.Collection("demands");

var demandschema = new SimpleSchema({
  ability: {type:array},
  language: {type: array}});

Demands.attachSchema(demandschema);

Contents Definition

DemandsSet=[
  {ability: ["laser eye", "rocky skin", "fly"], language: ["english", "latin", "hindu"]},
  {ability: ["sky-high jump", "rocky skin", "fly"], language: ["english", "latin", "japanese"]},
  {ability: ["rocky skin", "sky-high jump"], language: ["english", "latin", "russian"]}
];

Target Set

var TargetAbility = ["rocky skin", "fly"];
var TargetLanguage = ["english", "hindu"];

When I do a $in operation

Demands.find({ $and: [
  { ability: { $in: TargetAbility }}, 
  { language: { $in: TargetLanguage }}
]}).fetch();

I will return me with all records, while it is not correct, how can I perform such a find operation?

Upvotes: 0

Views: 735

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20226

$in: is not going to work for you because it looks for any match when comparing two arrays, not that all elements of one array must be present in the other.

You can write complete javascript functions to execute the required comparisons inside the mongodb query. See $where:

For example:

Demands.find({$where:
  "this.ability.indexOf(TargetAbility[0])   > -1 &&
   this.ability.indexOf(TargetAbility[1])   > -1 &&
   this.language.indexOf(TargetLanguage[0]) > -1 &&
   this.language.indexOf(TargetLanguage[1]) > -1" });

If your candidates have other than 2 entries each then you can write a more general form of this of course.

Note that Meteor apparently does not support the function() form of $where: but that restriction may be dated.

Also note that $where: cannot take advantage of indexes so performance may not be suitable for large collections.

Upvotes: 2

Related Questions