olivernn / lunr.js

A bit like Solr, but much smaller and not as bright
http://lunrjs.com
MIT License
8.87k stars 546 forks source link

Unable to search results by url #419

Open UncountedBrute2 opened 4 years ago

UncountedBrute2 commented 4 years ago

I have a very simple implementation like that of the docs which does the following: buildIndex() { let documents = []; this.sections.forEach(section => { section.links.forEach(link => { documents.push({ rowId: link.rowId, displayName: link.displayName, description: link.description, url: link.url }); }); }); this.searchIndex = lunr(function () { this.ref('rowId'); this.field('displayName'); this.field('description'); this.field('url'); documents.forEach(doc => { this.add(doc); }); }); }

When running a search with a url it is unable to find the record.

olivernn commented 4 years ago

Could you put together an example on jsfiddle (or similar) reproducing the issue? Without knowing what you are putting in the index it isn't possible to figure out why you aren't getting any results.

SageStarCodes commented 4 years ago

+1 The issue seems to be with tokenizing / indexing special characters, more specifically the forward slash /

My exapmple:

<template lang="pug">
  .search
    .container
      gb-input(type='text' autofocus=true clearable=true v-model="searchText" left-icon='search' prepend='Search' name='search')
      .suggestion-container {{suggestions}}
</template>
<script>
  import lunr from 'lunr'

  export default {
    name: "Search",
    data() {
      return {
        searchText: "",
        suggestions: null,
        idx: null,
        pageIndexes: [
          {
            "alternate": "/",
            "name": "Dashboard",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis",
            "id": "0"
          },
          {
            "alternate": "/users/me",
            "name": "My profile",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/users/me",
            "id": "1"
          },
          {
            "alternate": "/timetables",
            "name": "Timetables",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/timetables",
            "id": "2"
          },
          {
            "alternate": "/web",
            "name": "Web",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/web",
            "id": "3"
          },
          {
            "alternate": "/emails",
            "name": "Emails",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/emails",
            "id": "4"
          },
          {
            "alternate": "/users",
            "name": "Users",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/users",
            "id": "5"
          },
          {
            "alternate": "/payments",
            "name": "Payments",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/payments",
            "id": "6"
          },
          {
            "alternate": "/manage",
            "name": "Settings",
            "badge": "Page",
            "badgeColor": "white",
            "path": "/akadis/manage",
            "id": "7"
          }
        ]
      }
    },
    watch: {
      searchText: function(newVal, oldVal) {
        this.suggestions = this.idx.search(newVal + "*");
      }
    },
    mounted() {
      const pI = this.pageIndexes;
      this.idx = lunr(function() {
        this.field('alternate');
        this.field('name');
        pI.forEach((doc) => {
          this.add(doc);
        });
      });
      this.suggestions = this.idx.search("*");
    }
  }
</script>
tmurvv commented 3 years ago

I am having this issue also. In music it is very common to write composer/arranger i.e. Beethoven/Cohen. If I am searching the db for all Cohen arrangements, none are found.

var documents = [{title: 'My Composition', composer_arranger: 'Beethoven/Cohen'}];

var idx = lunr(function () {
     this.ref('title');
     this.field('composer_arranger')
     documents.forEach(function (doc) {
       this.add(doc)
     }, this)
   })

   console.log(idx.search('Cohen')) // returns []
rjimenezhsc commented 2 years ago

The tokenizer splits on spaces, so technically 'Beethoven/Cohen' would still be one "token".

However, 'Beethoven / Cohen' would be two (I assume '/' is removed)

If you want to search for it as it is, try

   console.log(idx.search('*Cohen'))

This should work since this tells Lunr to do a fuzzy search where the field ends with 'Cohen'.

More information on searching: https://lunrjs.com/guides/searching.html