Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

And operator not working when 2 indices have to match different values #470

Open
pedrovgs opened this issue Mar 24, 2025 · 2 comments
Open

Comments

@pedrovgs
Copy link

Given a document saving the documentId as a index field with strict tokenization config and another index field for the document content named content, after adding some data to the document, when we search using bool: "and" in our query, the result includes matches for individual index results instead of results matching both.

This is the document structure:

const index = new FlexSearch.Document({
	tokenize: "full",
  document: {
    id: "documentId",
    store: true,
    index: [
      {
        field: "content",
      },
      {
        field: "documentId",
        tokenize: "strict",
      },
    ],
  },
});

This is the data we add:

index.add(1, {
  documentId: "doc-1",
  content: "Content from document 1"
});
index.add(2, {
  documentId: "doc-2",
  content: "Content from document 2"
});

This is the query we execute:

const matches = index.search({
	enrich: true,
  bool: "and",
  index: [
  	{
    	field: "content",
      query: "document"
    },
    {
    	field: "documentId",
      query: "doc-1"
    }
  ]
})

The result obtained shows one array with 2 entries, one for the first index and another one for the second index, where I would be expecting a single result entry with matches for both indices:

Actual result:

[
  {
    "field": "content",
    "result": [
      {
        "id": 1,
        "doc": {
          "documentId": "doc-1",
          "content": "Content from document 1"
        }
      },
      {
        "id": 2,
        "doc": {
          "documentId": "doc-2",
          "content": "Content from document 2"
        }
      }
    ]
  },
  {
    "field": "documentId",
    "result": [
      {
        "id": 1,
        "doc": {
          "documentId": "doc-1",
          "content": "Content from document 1"
        }
      }
    ]
  }
]

Expected result:

[
  {
    "result": [
      {
        "id": 1,
        "doc": {
          "documentId": "doc-1",
          "content": "Content from document 1"
        }
      }
    ]
  }
]

I don't really know if the bool property as part of the document query, is just one API that I didn't understand when reading the documentation or it should work as I detailed above, but reading the docs, looks like the intention is to apply logical operators to a search query.

Image

I think there is a new API introduced in version 0.8.0 named resolvers, but I don't know if this is the one I should use. I tried to make it work with no luck tbh.

BWT @ts-thomas and the rest of the contributors, thank you for the hard work on the library and your contributions to the open-source community 😃

@ts-thomas
Copy link
Contributor

Unfortunately the readme is a bit outdated. I'm almost finished with the updated version, probably coming the next days. The boolean property was removed. There is a new Resolver feature which can chain boolean into a more complex expression: https://github.com/nextapps-de/flexsearch/blob/master/doc/resolver.md
Document Resolver is also supported, but it's limited to just use one field per resolver stage. This will be added in documention soon.

This is a snippet from my dev files:

  // some test data
  const data = [{
    "tconst": "tt0000001",
    "titleType": "short",
    "primaryTitle": "Carmencita",
    "originalTitle": "Carmencita",
    "isAdult": 0,
    "startYear": "1894",
    "endYear": "",
    "runtimeMinutes": "1",
    "genres": [
      "Documentary",
      "Short"
    ]
  },{
    "tconst": "tt0000002",
    "titleType": "short",
    "primaryTitle": "Le clown et ses chiens",
    "originalTitle": "Le clown et ses chiens",
    "isAdult": 0,
    "startYear": "1892",
    "endYear": "",
    "runtimeMinutes": "5",
    "genres": [
      "Animation",
      "Short"
    ]
  }];

  // create the document index
  const index = new Document({
    document: {
      id: "tconst",
      store: true,
      index: [{
        field: "primaryTitle",
        tokenize: "forward",
        encoder: Charset.LatinBalance
      },{
        field: "originalTitle",
        tokenize: "forward",
        encoder: Charset.LatinBalance
      }],
      tag: [{
        field: "startYear"
      },{
        field: "genres"
      }]
    }
  });

  // add test data
  for(let i = 0; i < data.length; i++){
    index.add(data[i]);
  }

  // perform a query + enrich results
  const result = new Resolver({
    index: index,
    query: "karmen",
    pluck: "primaryTitle",
    //enrich: true,
  }).or({
    index: index,
    query: "clown",
    pluck: "primaryTitle",

  }).and({
    index: index,
    query: "karmen",
    field: "primaryTitle",
    suggest: true
  }).not({
    index: index,
    query: "clown",
    pluck: "primaryTitle",
    enrich: true,
    resolve: true

  });

  // display results
  console.log(result);

Each resolver stage can access on a different field/index.

@pedrovgs
Copy link
Author

Thanks for the quick response @ts-thomas. Let me test this new API later. For now, I'm just filtering results manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants