Як перевірити, чи містить поле масиву унікальне значення чи інший масив у MongoDB?


143

Зараз я використовую mongodb.

У мене є колекція блогу, і в блозі є теги, які є масивом, наприклад

blogpost1.tags = ['tag1', 'tag2', 'tag3', 'tag4', 'tag5']
blogpost2.tags = ['tag2', 'tag3']
blogpost3.tags = ['tag2', 'tag3', 'tag4', 'tag5']
blogpost4.tags = ['tag1', 'tag4', 'tag5']

Як мені зробити ці пошуки

  1. містить 'tag1'
  2. містить ['tag1', 'tag2'],
  3. містить будь-який із ['tag3', 'tag4']

Відповіді:


219

Спробуйте це:

db.blogpost.find({ 'tags' : 'tag1'}); //1
db.blogpost.find({ 'tags' : { $all : [ 'tag1', 'tag2' ] }}); //2
db.blogpost.find({ 'tags' : { $in : [ 'tag3', 'tag4' ] }}); //3

6
Про це добре зафіксовано у довідці: mongodb.org/display/DOCS/…
Скотт Ернандес

2
для $ all це означає всі елементи ТА у вираженому порядку чи це просто не упорядковано?
redben

2
@ScottHernandez Я не бачу, що вони згадують, що поле, яке ви використовуєте в якості пошуку, може бути масивом, і як це обробляється. "поле: {$ в: масив}". Що відбувається під час пошуку масиву в масиві масивів? Не визначено.
Zut

Чи є який-небудь індексинг, який ми можемо зробити на масиві, щоб зупинити повтор? Якщо так, будь ласка, вкажіть, як.
Хітеш Джоші

1
@redben його не упорядковано, як написано в документах: $ all DOCS оператора . Просто прочитайте приклад частини, і ви побачите.
Маттіас Б

5

Мій досвід полягає в тому, що для (2) наступне рішення набагато швидше, ніж рішення з "$ all":

db.blogpost.find({ $and: [ {tags: 'tag1'} ,{tags: 'tag2'} ] });

але якщо чесно, я не чому. Мені було б цікаво, якщо хтось знає.


1
До речі, щойно тестували його в індексованому списку ключових слів. Абсолютно такий же результат з $ і і $ all
isox

Можливо, це тим часом змінилося з новішими версіями.
heinob

Це побічно. Для "$ і", mongodb робить логічну операцію "і". Тому, якщо перший вираз помилковий, другий не враховується. Це означає менше обробки.
kubudi

Але це має відбутися і з "$ all", чи не так?
heinob

1
$ all - це, ймовірно, два пошуку в індексі, $ і, ймовірно, один пошук з послідовним скануванням результату.
Еван Керролл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.