Znajdź dokument z tablicą zawierającą określoną wartość

Jeśli mam ten schemat...

person = {
    name : String,
    favoriteFoods : Array
}

... gdzie tablica {[2] } jest wypełniona łańcuchami. Jak mogę znaleźć wszystkie osoby, które mają "sushi" jako swoje ulubione jedzenie za pomocą mangusty?

Liczyłem na coś w stylu:

PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});

(wiem, że nie ma $contains w mongodb, po prostu wyjaśniając, co spodziewałem się znaleźć, zanim poznałem rozwiązanie)

Author: ᴀʀᴍᴀɴ, 2013-08-09

9 answers

Ponieważ favouriteFoods jest prostą tablicą łańcuchów, możesz po prostu zapytać to pole bezpośrednio:

PersonModel.find({ favouriteFoods: "sushi" }, ...);

Ale zalecałbym również, aby tablica łańcuchów była jawna w twoim schemacie:

person = {
    name : String,
    favouriteFoods : [String]
}
 495
Author: JohnnyHK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-13 16:36:12

Nie ma $contains operatora w mongodb.

Możesz użyć odpowiedzi od JohnnyHK, ponieważ to działa. Najbliższa analogia do Zawiera, które ma mongo jest $in, używając tego twoje zapytanie wyglądałoby następująco:

PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);
 104
Author: Alistair Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-09 14:46:14

Wydaje mi się, że $all byłoby bardziej odpowiednie w tej sytuacji. Jeśli szukasz osoby, która lubi sushi to zrób :

PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})

Jak możesz chcieć filtrować więcej wyszukiwania, Tak:

PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})

$in jest jak OR I $all jak i. Sprawdź to: https://docs.mongodb.com/manual/reference/operator/query/all/

 45
Author: Pobe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-19 15:31:29

W przypadku, gdy potrzebujesz znaleźć dokumenty zawierające elementy NULL wewnątrz tablicy pod-dokumentów, znalazłem to zapytanie, które działa całkiem dobrze:

db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})

To zapytanie pochodzi z tego postu: MongoDb query array with null values

To było świetne znalezisko i działa znacznie lepiej niż moja początkowa i zła wersja (która okazała się działać dobrze tylko dla tablic z jednym elementem):

.find({
    'MyArrayOfSubDocuments': { $not: { $size: 0 } },
    'MyArrayOfSubDocuments._id': { $exists: false }
})
 27
Author: Jesus Campon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:19

W przypadku, gdy tablica zawiera obiekty, na przykład jeśli favouriteFoods jest tablicą obiektów o następującej wartości:

{
  name: 'Sushi',
  type: 'Japanese'
}

Możesz użyć następującego zapytania:

PersonModel.find({"favouriteFoods.name": "Sushi"});
 21
Author: Kfir Erez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-08 10:37:32

Dla Loopback3 wszystkie podane przykłady nie działały dla mnie, lub tak szybko, jak przy użyciu REST API. Ale to pomogło mi znaleźć dokładną odpowiedź, której potrzebowałem.

{"where":{"arrayAttribute":{ "all" :[String]}}}

 1
Author: Mark Ryan Orosa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 02:43:31

Chociaż zgadzam się z find() jest najskuteczniejsza w Twojej usecase. Nadal istnieje $match Framework agregacji, aby ułatwić Zapytanie o dużą liczbę wpisów i wygenerować małą liczbę wyników, które trzymają wartość dla Ciebie, szczególnie w przypadku grupowania i tworzenia nowych plików.

  PersonModel.aggregate([
            { 
                 "$match": { 
                     $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ]  }
             },
             { $project : {"_id": 0, "name" : 1} }
            ]);
 0
Author: FullStack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-18 06:18:39

Jeśli chcesz użyć czegoś w rodzaju operatora "contains" poprzez javascript, zawsze możesz użyć do tego wyrażenia regularnego...

Np. Powiedz, że chcesz odzyskać Klienta o nazwie "Bartolomew"

async function getBartolomew() {
    const custStartWith_Bart = await Customers.find({name: /^Bart/ }); // Starts with Bart
    const custEndWith_lomew = await Customers.find({name: /lomew$/ }); // Ends with lomew
    const custContains_rtol = await Customers.find({name: /.*rtol.*/ }); // Contains rtol

    console.log(custStartWith_Bart);
    console.log(custEndWith_lomew);
    console.log(custContains_rtol);
}
 0
Author: Alingenomen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 21:58:35

Wiem, że ten temat jest stary, ale dla przyszłych ludzi, którzy mogliby zastanawiać się nad tym samym pytaniem, innym niewiarygodnie nieefektywnym rozwiązaniem może być zrobienie:

PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'});

Pozwala to uniknąć wszystkich optymalizacji przez MongoDB, więc nie używaj go w kodzie produkcyjnym.

 -20
Author: user3027146,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 15:58:15