MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Mongoose - Wyszukaj tekst w trzech polach na podstawie wyniku lub wagi

"indeks tekstowy" i wyszukiwanie jest prawdopodobnie najlepszą opcją tutaj, o ile szukasz całych słów.

Dodanie indeksu tekstowego do definicji schematu jest dość proste:

BookSchema.index(
    {
         "name": "text",
         "description": "text",
         "body": "text"
    },
    {
        "weights": {
            "name": 5,
            "description": 2
        }
    }
)

Pozwala to na wykonywanie prostych wyszukiwań z „ustawieniem” wag dla pól:

Book.find({ "$text": { "$search": "Holiday School Year" } })
    .select({ "score": { "$meta": "textScore" } })
    .sort({ "score": { "$meta": "textScore" } })
    .exec(function(err,result) {

    }
);

Tam, gdzie każdy dopasowany termin będzie rozpatrywany w odniesieniu do pola, w którym został znaleziony, w którym ma największą wagę i liczbę wystąpień.

Przypisanie wag jest dołączone do „indeksu”, więc definicja jest wykonywana jednorazowo i nie można jej zmienić. Innym ograniczeniem jest to, że przy „wyszukiwaniu tekstowym” nie bierze się pod uwagę „częściowych” słów. Na przykład „ci” nie pasuje do „Miasto” lub „Obywatel”, a do tego potrzebne byłoby zamiast tego wyrażenie regularne.

Jeśli potrzebujesz większej elastyczności lub ogólnie musisz mieć możliwość dynamicznej zmiany wagi wyników, potrzebujesz czegoś w rodzaju struktury agregacji lub mapReduce.

Struktura agregacji nie może jednak przeprowadzić "logicznego" dopasowania operacja (może filtrować przez $match operatora, ale nie „logicznego” dopasowania ) „wyrażenia regularnego” do Twoich terminów. Możesz pracować z pojedynczymi słowami i "dokładnymi" dopasowaniami, jeśli to pasuje.

Book.aggregate(
    [
        { "$match": {
            "$or": [
                { "name": /Holiday/ },
                { "description": /Holiday/ },
                { "body": /Holiday/ }
            ]
        }},
        { "$project": {
            "name": 1,
            "description": 1,
            "body": 1,
            "score": {
                "$add": [
                    { "$cond": [{ "$eq": [ "$name", "Holiday" ] },5,0 ] },
                    { "$cond": [{ "$eq": [ "$description", "Holiday" ] },2,0 ] },
                    { "$cond": [{ "$eq": [ "$body", "Holiday" ] },1,0 ] }
                ]
            }
        }},
        { "$sort": { "score": -1 } }
    ],
    function(err,results) {

    }
)

Jako potok agregacji używa struktury danych do zapytań, w których możesz zmienić parametry wagi w każdym wykonaniu na takie, jakich aktualnie potrzebujesz.

MapReduce ma podobną zasadę, w której można uwzględnić obliczony „wynik” w części klucza podstawowego emitowanego jako element wiodący. MapReduce naturalnie sortuje wszystkie dane wejściowe emitowane przez ten klucz jako optymalizację podawania do funkcji zmniejszania. Nie możesz jednak dalej sortować ani „ograniczać” takiego wyniku.

Są to zazwyczaj opcje, na które należy spojrzeć i zdecydować, które najlepiej pasują do Twojego przypadku.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mapa/redukcja MongoDB w wielu kolekcjach?

  2. Praca z PTVS, IronPython i MongoDB

  3. Projekt MongoDB zaktualizował rekord w zagnieżdżonej tablicy w zapytaniu findAndModify

  4. Jak zainstalować php-mongo na CentOS 5.3?

  5. Zmiana rozmiaru obrazów za pomocą Nodejs i Imagemagick