FTS resulting documents are empty (all properties are null)

Hi,

I have a list of “items” that i would like to search in and retrieve documents by name. so far, i have created an index already and the search seems to work… kind of. The rows get returned but all of the row values are null. FullTextQueryRow works different than an Resultset. I must be missing something there but i don’t really know what im doing wrong. The index is there and the query runs but yet the documents it returns are empty.
Also, is there a way to check if that index has already been created? Right now i just create it everytime i run a search and i think this is not the way i should be doing it.

Here is my code.

public static List<Search> SearchItems(string searchterm)
    {
        List<Search> searches = new List<Search>();

        if (String.IsNullOrEmpty(searchterm))
        {
            searches = LoadAllListItems();
        }

        else
        {

            bool startswithletter = !String.IsNullOrEmpty(searchterm) && Char.IsLetter(searchterm[0]);

            if (startswithletter)
            {

                using (var searchesDatabase = new Database("search"))
                {   
                    searchesDatabase.CreateIndex(new[] { "key", "itemnamenl" }, IndexType.FullTextIndex, null);
                    var query = Query.Select(SelectResult.Expression(Expression.Property("itemnamenl")),
                                         SelectResult.Expression(Expression.Property("key")),
                                         SelectResult.Expression(Expression.Property("itemid"))
                        )
                    .From(DataSource.Database(searchesDatabase))
                    .Where(Expression.Property("itemnamenl").Match(searchterm+ "*"))
                    .OrderBy(Ordering.Property("itemnamenl"));


                    try
                    {
                        var rows = query.Run();

                        if (rows != null)
                        {
                            foreach (var row in rows)            //row  properties always are null!
                            {
                                var document = row;
                                searches.Add(
                                    new Search
                                          {
                                          key = document.GetString(key: "key"),
                                          itemnamenl = document.GetString(key: "itemnamenl"),
                                          itemid = document.GetString(key: "itemid")

                                   });

                            }
                        }
                    }
                    catch (Exception e)
                    {
                        var ex = e;
                    }
                }
            }

            else

            {

                using (var searchesDatabase = new Database("search"))
                {
                    searches = new List<Search>();
                    searchesDatabase.CreateIndex(new[] { "key", "itemnamenl" }, IndexType.FullTextIndex, null);
                    var query = Query.Select(SelectResult.Expression(Expression.Property("key")),
                                             SelectResult.Expression(Expression.Property("itemid")),
                                             SelectResult.Expression(Expression.Property("itemnamenl"))
                     )
                    .From(DataSource.Database(searchesDatabase))
                    .Where(Expression.Property("key").Match(zoekterm))
                    .OrderBy(Ordering.Property("itemnamenl"));

                    try
                    {
                        var rows = query.Run();

                        if (rows != null)
                        {
                            foreach (var row in rows)
                            {
                                var document = row;
                                searches.Add(
                                  new Search
                                   {
                                   key = document.GetString(key: "key"),
                                   itemnamenl = document.GetString(key: "itemnamenl"),
                                   itemid = document.GetString(key: "itemid")

                                  });
                            }
                        }

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace);
                    }

                }

            }

        }
        return searches;
    }

I would recommend creating the FTS indexes when you create/open the database. Do not do it every time you run the query.

At a glance, your expression looks OK to me so I guess will ask some basic questions

  1. Can you confirm that your database does in fact have document that matches the criteria. (In fact would be great if you can share the JSON doc that you expect to receive so we can check to see if the criteria is correct)
  2. To narrow it down, can you try and do an exact match instead of wildcard to see if problem lies there. So choose a string that you know definitely exists and do a exact match
  3. When you iterate over the rows, what do you get when you inspect “row”
    Example :
       ResultSet resultRows = change.getRows();
       Result row;
                                         
       while ((row = resultRows.next()) != null) {
              // print out value of row.toMap() . What do you get ?
      }
                                      
  1. Which DB version are you using

Hi,

Yes i do have documents that match the search im doing. Nothing appears to be wrong with the search logic itself.

{
"_sync": {
"rev": "1-928c55b18ae6ed6e2cca59f2d3ee56fd",
"sequence": 7,
"recent_sequences": [
  7
],
"history": {
  "revs": [
    "1-928c55b18ae6ed6e2cca59f2d3ee56fd"
  ],
  "parents": [
    -1
  ],
  "channels": [
    null
  ]
},
"cas": "",
"time_saved": "2017-08-18T09:32:07.3570852+02:00"
},
"deleteFlagSetDate": "0001-01-01T00:00:00",
"itemid": "97764d21-375b-48ee-8462-35a0ed4d0000",
"itemnamefr": "CADRE PP KENYA 21X29.7 IVOI///",
"itemnamenl": "CADRE PP KENYA 21X29.7 IVOI///",
"key": "3499888022476"
}

thats one of the documents. If i type “Cad” for example. i Know for sure this document will be in there, among others. I tried using an exact match and that works aswell.

when i inspect the row that gets returned when i run the query. the properties all are null. Im not sure if im doing it the right way. I am just looking in my foreach loop and just evalute the searches. than one of the documents and see nothing is in them. i will try it your way using your code snippet.

Im using the latest version Couchbase lite version 14

The problem is:

CreateIndex(new[] { "key", "itemnamenl" }, IndexType.FullTextIndex, null)

A FTS index should only have a single term, for the property whose text you want to index. So take out "key",.

There’s no harm in creating the index if it already exists (it’s a no-op), but it will take a little time to check. Not a problem if you only call SearchItems occasionally, like in response to user action, but if you call it a lot you should consider only creating the index before the first time the query runs.

Hello,

I have updated the code but am still getting the same results :frowning:.

This does seem to be happening in testing too…I’ll try to get to the bottom of it but in the meantime you should file a ticket. I’ll work out if it’s a problem with .NET or with LiteCore.

1 Like

Ok I found that quicker than I thought -> https://github.com/couchbase/couchbase-lite-core/issues/236

The solution seems pretty easy. I’ll put up a PR for the team to look at since I will be off tomorrow.

1 Like

Alright.

When does the new update release? I’m really looking forward to it :slight_smile:.

Thanks for the feedback from you all!

DB015 was just released a day or two ago, so in about two weeks this fix will be in the next DB.

Very nice :smiley: thanks!